1

我有这个非常简单的 XML

<Customer>
   <BirthDate>1958-05-31 00:00:00</BirthDate>
</Customer>

我想提取没有小时部分的 BirthDate。

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

我在这个网站上测试了这个 XPath :

/Customer/BirthDate/substring(text(), 1, 10)

我还测试了这个 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();
}

这是一个 XPathException,没有任何内部异常的消息:

'/Customer/BirthDate/substring(text(), 1, 10)' 具有无效标记。

Wellllllll ..... 我该怎么办?

4

5 回答 5

2

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

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

于 2013-04-17T20:38:36.740 回答
1

我会选择你的第一个选项。选择值,将字符串解析为日期,然后格式化日期。而不是一次完成所有这些。

 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();
于 2013-04-17T20:29:12.757 回答
1

您可以像这样评估单个值:

var expr2 = navigator.Evaluate("substring(/Customer/BirthDate, 1, 10)");
Console.WriteLine(expr2);

但这只会给你一个字符串。

以下表达式似乎编译并返回了一个节点集,但没有提取子字符串,总是返回完整的字符串:

var expr2 = navigator.Compile("/Customer/BirthDate[substring(text(), 1, 8)]");
于 2013-04-17T20:44:58.720 回答
1

利用:

substring(/Customer/BirthDate, 1, 10)

在 XPath 1.0 中工作。

正如菲利普的回答所指出的,您尝试的语法在 XPath 2.0 中有效,但在 1.0 中无效,即 .NET 支持的版本

于 2013-04-17T21:43:08.930 回答
0

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

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 中,然后你可以用它做任何你想做的事情。

于 2013-04-17T20:30:30.910 回答