我有这个非常简单的XML
<Customer>
<BirthDate>1958-05-31 00:00:00</BirthDate>
</Customer>
我想在没有小时部分的情况下提取BirthDate。
编辑:必须在XPath语句中完成,而不是在客户端代码中完成。
我已使用此website测试此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 .....我该怎么办?
答案 0 :(得分:2)
编辑:必须在XPath语句中完成,而不是在客户端代码中完成。
.net内置的XPath支持仅支持XPath 1.0。 XPath 1.0不支持位置步骤中的函数,因此您必须使用支持XPath 2.0的.net的第三方库,如XmlPrime,Saxxon或Query Machine。
答案 1 :(得分: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();
答案 2 :(得分:1)
您可以像这样评估单个值:
var expr2 = navigator.Evaluate("substring(/Customer/BirthDate, 1, 10)");
Console.WriteLine(expr2);
但这只会给你一个字符串。
以下表达式似乎编译并返回一个节点集,但没有提取子字符串,总是返回完整的字符串:
var expr2 = navigator.Compile("/Customer/BirthDate[substring(text(), 1, 8)]");
答案 3 :(得分:1)
使用:
substring(/Customer/BirthDate, 1, 10)
在XPath 1.0中有效。
正如Philip的回答所指出的那样,你尝试过的语法在XPath 2.0中是有效的,但在1.0中则没有,那就是.NET支持的版本
答案 4 :(得分: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中,然后你会用它做任何你想做的事。