XPathExpression AddSort fails
本文关键字:fails AddSort XPathExpression | 更新日期: 2023-09-27 18:11:50
我试图从xpath查询排序结果,但它失败了。
Ooutput:
ABC
DEF
但我期待:
DEF
ABC
源代码是这样的,它使用XML表达式并对结果进行排序:
var doc = new XPathDocument("testmsg2.xml");
var nav = doc.CreateNavigator();
const string query = "//Z/X/Code";
var expr = nav.Compile(query);
expr.AddSort("Code",
XmlSortOrder.Descending,
XmlCaseOrder.None,
"",
XmlDataType.Text);
switch (expr.ReturnType)
{
case XPathResultType.NodeSet:
var nodes = (XPathNodeIterator)nav.Evaluate(expr);
while (nodes != null && nodes.MoveNext())
{
if (nodes.Current == null)
continue;
if (nodes.Current.HasChildren)
{
var childIter = nodes.Current.SelectChildren(XPathNodeType.All);
while (childIter.MoveNext())
{
if (childIter.Current != null)
Console.WriteLine(childIter.Current.Value);
}
}
else
{
Console.WriteLine(nodes.Current.Value);
}
}
break;
}
对于这个示例,XML文件是简化的:
<?xml version="1.0" encoding="utf-8"?>
<Z>
<X>
<Code>ABC</Code>
</X>
<X>
<Code>DEF</Code>
</X>
</Z>
AddSort
方法接受一个XPath表达式,该表达式在上下文中绑定到已编译的XPathExpression
。在您的示例中,XPathExpression
是针对<Code>
元素编译的。执行AddSort("Code")
意味着您有以下XML:
<Code>
<Code>
</Code>
</Code>
相反,您可以将表达式编译为X
:
const string query = "//Z/X";
或者你可以在当前节点(Code
)上排序,.
:
expr.AddSort(".", XmlSortOrder.Descending, XmlCaseOrder.None, "", XmlDataType.Text);
路径//Z/X/Code
选择Code
元素,那么Sort需要使用适当的相对表达式,在您的情况下
expr.AddSort(".",
XmlSortOrder.Descending,
XmlCaseOrder.None,
"",
XmlDataType.Text);
在AddSort()中使用"."代替"Code"从查询中删除"/Code",这取决于您是想选择x节点还是Code节点。目前,您正在查询Code-node,然后尝试通过将XPath"Code"应用于结果返回来对它们进行排序。但是相对于 Code-node,没有匹配"Code" 的内容。
使用Linq to Xml
using System.Xml.XPath;
var document = XDocument.Parse(@"<Z>
<X>
<Code>ABC</Code>
</X>
<X>
<Code>DEF</Code>
</X>
</Z>");
var codeValues = document.XPathSelectElements("//Z/X/Code")
.Select(e => e.Value)
.OrderByDescending(e => e);
如果你愿意,你可以进一步简化它。不过你需要考虑性能。如果您的xml文件很大,我想这将不会执行得很好。如果您只有小文件,那么这样做的简单性胜过了小的性能损失。