C# 使用;复杂的;c语言中的XPath#

C# 使用;复杂的;c语言中的XPath#,c#,xpath,C#,Xpath,我有一个非常简单的XML <Customer> <BirthDate>1958-05-31 00:00:00</BirthDate> </Customer> 我还测试了这个XPath: /Customer/BirthDate/substring(., 1, 10) 网站给了我预期的结果。但是我的C#程序给了我一个运行时错误 以下是测试程序: var content = @"<Customer><BirthDate>

我有一个非常简单的XML

<Customer>
   <BirthDate>1958-05-31 00:00:00</BirthDate>
</Customer>
我还测试了这个XPath:

/Customer/BirthDate/substring(., 1, 10)
网站给了我预期的结果。但是我的C#程序给了我一个运行时错误

以下是测试程序:

var content = @"<Customer><BirthDate>1958-05-31 00:00:00</BirthDate></Customer>";

using (var memStream = new MemoryStream(Encoding.Default.GetBytes(content)))
{
    var doc = new XPathDocument(memStream);
    var navigator = doc.CreateNavigator();

    /// GET THE "RAW" VALUE. WORKING
    var expr = navigator.Compile("/Customer/BirthDate");
    var iter = navigator.Select(expr);
    Console.WriteLine("BirthDate: {0}", iter.Current.Value);

    /// GET THE "TRANSFORMED" VALUE. NOT WORKING
    var expr2 = navigator.Compile("/Customer/BirthDate/substring(text(), 1, 8)");
    var iter2 = navigator.Select(expr2);
    Console.WriteLine("BirthDate: {0}", iter2.Current.Value);

    Console.ReadKey();
}
var内容=@“1958-05-31 00:00:00”;
使用(var memStream=newmemoryStream(Encoding.Default.GetBytes(content)))
{
var doc=新的XPathDocument(memStream);
var navigator=doc.CreateNavigator();
///获取“原始”值。正在工作
var expr=navigator.Compile(“/Customer/BirthDate”);
var iter=navigator.Select(expr);
WriteLine(“生日:{0}”,iter.Current.Value);
///获取“转换”值。不工作
var expr2=navigator.Compile(“/Customer/BirthDate/substring(text(),1,8)”);
var iter2=navigator.Select(expr2);
WriteLine(“生日:{0}”,iter2.Current.Value);
Console.ReadKey();
}
这是一个XPathException,没有任何innerexception,包含以下消息:

“/Customer/BirthDate/substring(text(),1,10)”具有无效令牌


嗯。。。。。我该怎么办?

我同意你的第一个选择。选择值,将字符串解析为date,然后格式化日期。而不是一次完成这一切

 var expr = navigator.Compile("/Customer/BirthDate");
 var iter = navigator.Select(expr);
 var formatted dates = iter
             .Select(i=>i.Current.Value)
             .Select(x => DateTime.Parse(x))
             .Select(x=> d.ToString(put desired format here))
             .ToArray();

我同意你的第一个选择。选择值,将字符串解析为date,然后格式化日期。而不是一次完成这一切

 var expr = navigator.Compile("/Customer/BirthDate");
 var iter = navigator.Select(expr);
 var formatted dates = iter
             .Select(i=>i.Current.Value)
             .Select(x => DateTime.Parse(x))
             .Select(x=> d.ToString(put desired format here))
             .ToArray();

我不知道你为什么不简单地使用:

var doc = new XPathDocument(memStream);
            var navigator = doc.CreateNavigator();

            /// GET THE "RAW" VALUE. WORKING
            var expr = navigator.Compile("/Customer/BirthDate");
            var iter = navigator.Select(expr);
            Console.WriteLine("BirthDate: {0}", iter.Current.Value);

            /// GET THE "TRANSFORMED" VALUE. NOT WORKING
            var result = iter.Current.Value.ToString().Substring(0, 10);
            Console.WriteLine("BirthDate: {0}", result);   

将子字符串值放入一个新的var中,然后您可以对其执行任何操作。

我不知道您为什么不简单地使用:

var doc = new XPathDocument(memStream);
            var navigator = doc.CreateNavigator();

            /// GET THE "RAW" VALUE. WORKING
            var expr = navigator.Compile("/Customer/BirthDate");
            var iter = navigator.Select(expr);
            Console.WriteLine("BirthDate: {0}", iter.Current.Value);

            /// GET THE "TRANSFORMED" VALUE. NOT WORKING
            var result = iter.Current.Value.ToString().Substring(0, 10);
            Console.WriteLine("BirthDate: {0}", result);   
将子字符串值放入一个新的var中,然后您可以使用它执行任何操作

编辑:必须在XPath语句中完成,而不是在客户端代码中完成

.net对XPath的内置支持仅支持XPath 1.0。XPath 1.0不支持位置步骤中的函数,因此您必须使用支持XPath 2.0的第三方.net库,如或

编辑:必须在XPath语句中完成,而不是在客户端代码中完成


.net对XPath的内置支持仅支持XPath 1.0。XPath 1.0不支持位置步骤中的函数,因此您必须使用支持XPath 2.0的第三方.net库,如或。

您可以这样计算单个值:

var expr2 = navigator.Evaluate("substring(/Customer/BirthDate, 1, 10)");
Console.WriteLine(expr2);
但这只会得到一个字符串

以下表达式似乎编译并返回节点集,但未提取任何子字符串,始终返回完整字符串:

var expr2 = navigator.Compile("/Customer/BirthDate[substring(text(), 1, 8)]");

您可以这样计算单个值:

var expr2 = navigator.Evaluate("substring(/Customer/BirthDate, 1, 10)");
Console.WriteLine(expr2);
但这只会得到一个字符串

以下表达式似乎编译并返回节点集,但未提取任何子字符串,始终返回完整字符串:

var expr2 = navigator.Compile("/Customer/BirthDate[substring(text(), 1, 8)]");
使用:

在XPath1.0中可以使用

正如Philip在回答中指出的,您尝试的语法在XPath 2.0中有效,但在1.0中无效,即.NET支持的版本使用:

这在XPath1.0中有效


正如Philip在回答中指出的那样,您尝试的语法在XPath 2.0中有效,但在1.0中无效,这是.NET支持的版本

我编辑了我的问题以增加这种精度:它必须在XPath语句中完成,而不是在客户端代码中。您可以尝试xslt和xml转换。那可能行得通。但是xpath是一个查询,它过滤/选择元素,而不是格式化元素。我编辑我的问题是为了增加精度:它必须在xpath语句中完成,而不是在客户端代码中完成。您可以尝试xslt和xml转换。那可能行得通。但xpath是一个过滤/选择元素的查询,它不格式化元素。我编辑问题是为了添加此精度:必须在xpath语句中完成,而不是在客户端代码中完成。我编辑问题是为了添加此精度:必须在xpath语句中完成,而不是在客户端代码中完成。xpath 1.0不支持子字符串函数。参见参考@Alexander Yes,它支持该功能。但是,它不支持位置步骤中的函数。感谢您对XPath 2.0库的建议。XPath 1.0确实支持子字符串函数。参见参考@Alexander Yes,它支持该功能。然而,它不支持位置步骤中的函数。感谢您的XPath 2.0库建议。第二个表达式返回括号内表达式为true的所有
出生日期
节点-在本例中,即包含任何文本的所有节点。第二个表达式返回括号内的表达式为true—在本例中为包含任何文本的所有节点。