【问题标题】:Sorting XML with a namespace使用命名空间对 XML 进行排序
【发布时间】:2012-04-25 20:50:16
【问题描述】:

我发现的大多数关于排序 XML 查询的示例都不包含命名空间。其中一些确实如此,但我没有找到任何在有命名空间时执行查询和排序的示例。

 <Search xmlns="http://whatever.whatever.com/gg/whatever">
 <BinSet Type="Category">
 <Bin>
  <BinName>Clothing</BinName>
  <BinItemCount>804</BinItemCount>
   <BinParameter>
    <Name>Category</Name>
    <Value>Women's Apparel</Value>
  </BinParameter>
</Bin>
 <Bin>
  <BinName>Tools</BinName>
  <BinItemCount>126</BinItemCount>
   <BinParameter>
    <Name>Category</Name>
    <Value>Tools, handtools and hardware</Value>
  </BinParameter>
</Bin>
</BinSet>
</Search>

我对 XML 没有任何控制权,所以我必须处理命名空间。此外,XML 中大约有 50 条这样的记录,它只是更大的 XML 文件的一部分。

Dim nsuri as string = "http://whatever.whatever.com/gg/whatever"
Dim xpath as string = "dd:Search/dd:BinSet[Type="Category"]/*"
Dim nav As XPathNavigator = doc.CreateNavigator()
Dim exp As XPathExpression = nav.Compile(xpath)
Dim nsmgr As New XmlNamespaceManager(nav.NameTable)
nsmgr.AddNamespace("dd", nsuri)
exp.SetContext(nsmgr)

exp.AddSort("BinParameter/Value", XmlSortOrder.Ascending, XmlCaseOrder.UpperFirst, "en-US", XmlDataType.Text)

' now process in sorted order
Dim iterator As XPathNodeIterator = nav.Select(exp)
While iterator.MoveNext
    Dim nav2 As XPathNavigator = iterator.Current.Clone
    nav2.MoveToFirstChild()
    Debug.WriteLine(nav2.Value) 
End While

我看到的所有示例都显示了如何对直接子节点进行排序,例如我的示例 XML 中的 BinName 或 BinItemCount。但我需要所有这些信息,并且需要在 BinParameter/Value 节点上进行排序。我已经尝试了所有我能想到的方法......

最后要注意的是,我真的不在乎使用 XPathNodeIterator 或 XPathNavigator。以前我返回一个包含所有这些记录的 XmlNodeList,我的调用例程将遍历节点列表以形成链接,如下所示:

<a href="mypage.aspx?si=Tools">Tools, handtools and hardware (126)</a>
<a href="mypage.aspx?si=Clothing">Women's Apparel (804)</a>

有谁知道如何使用命名空间通过嵌套的子节点“值”对这个 XML 进行排序?

另外,您是否知道在 XmlNodeList 或其他 .Net 对象中返回排序结果的最快方法,以便我可以访问所有值:BinName、BinItemCount、Name 和 Value?我不熟悉 XPathNavigator 或 XPathNodeIterator。

谢谢。

【问题讨论】:

    标签: .net xml


    【解决方案1】:

    尝试将xpath 变量设置为

    /dd:Sets/dd:Bin/dd:BinParameter
    

    并使用以下 AddSort 行

    exp.AddSort("dd:Value", XmlSortOrder.Ascending, XmlCaseOrder.UpperFirst, "en-US", XmlDataType.Text)
    

    (注意所有元素的 dd: 前缀)

    编辑:

    Dim iterator As XPathNodeIterator = nav.Select(exp, nsmgr)
    

    【讨论】:

    • 对不起...我没有包含我的 XPath 声明。它确实包含前缀。它是:
    • 是吗? (请注意,您的 AddSort 表达式不包含命名空间前缀)
    • 我很难弄清楚如何回复...对不起。我会试试你的建议。我唯一担心的是我还需要 BinName 和 BinItemCount 的值。所以我的 XPath 是 /dd:Sets/dd:Bin。通过将 XPath 设置为您推荐的深度,似乎不会包含这些值?我会试试的,然后告诉你。谢谢!顺便说一句,我的 XPath 确实包含命名空间的正确前缀。
    • 我的 XPath 是“dd:Sets/*”。那是因为我还需要 BinName 和 BinItemCount 节点。因为我还需要每个 。当我在 Addsort 中包含前缀时,我在“Dim iterator As XPathNodeIterator = nav.Select(exp)”这一行上收到错误,说“需要命名空间管理器或 XsltContext。此查询具有前缀、变量或用户定义的函数。 "
    • 根据 AddSort 的实现方式,可能需要使用“深度”XPath,但只要表达式有效,这应该很容易测试。如果需要,应该很容易执行两个 XPath 表达式,一个用于检索顶部节点,一个用于对 Bin/Values 进行排序。附言。 Select 方法可能需要对命名空间管理器的引用,请参阅编辑后的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多