LINQ按XML查询排序

时间:2014-10-27 12:28:08

标签: xml vb.net linq

您好我有以下问题:

我正在尝试在XML文件上执行以下操作:根据STRING的ID属性对所有STRUCT进行排序。但是返回一个CONTENT对象列表。 XML可以包含多个元素。

<OBJECT>
  <CONTENT>
     <STRUCT>
        <STRING ID="2">string</STRING>
     </STRUCT>
     <STRUCT>
        <STRING ID="1">string1</STRING>
     </STRUCT>
   </CONTENT>
</OBJECT>
<OBJECT>
  <CONTENT>
     <STRUCT>
        <STRING ID="345">string</STRING>
     </STRUCT>
     <STRUCT>
        <STRING ID="333">string</STRING>
     </STRUCT>
   </CONTENT>
</OBJECT>

我正在使用以下LINQ查询,但字符串未被排序:

Dim Contents = From nm In origXML.Descendants("CONTENT")
    Let ID = nm.Element("STRUCT").Element("STRING").Attribute("ID")
    Order By ID Ascending
    Select nm

For Each xmlString In Contents....

期望的输出

<OBJECT>
  <CONTENT>
     <STRUCT>
        <STRING ID="1">string</STRING>
     </STRUCT>
     <STRUCT>
        <STRING ID="2">string1</STRING>
     </STRUCT>
   </CONTENT>
</OBJECT>
<OBJECT>
  <CONTENT>
     <STRUCT>
        <STRING ID="333">string</STRING>
     </STRUCT>
     <STRUCT>
        <STRING ID="345">string</STRING>
     </STRUCT>
   </CONTENT>
</OBJECT>

我知道必须有其他方法可以做到这一点,但我想知道是否可以使用LINQ?

由于

罗布

2 个答案:

答案 0 :(得分:0)

我不认为单个linq查询可以为您提供所需的输出。为了正确创建一个与原始文档具有相同结构的新xml文档,您需要将多个嵌套的linq查询应用于原始xml文档。

假设您的XML的根节点是<OBJECTS>,以下代码应该为您提供所需的输出:

Dim xElement As XElement = New XElement("OBJECTS",
                              From obj In origXML.Descendants("OBJECT")
                              Select New XElement("OBJECT",
                                 From content In obj.Descendants("CONTENT")
                                 Select New XElement("CONTENT",
                                    From st In content.Descendants("STRUCT")
                                    Let ID = Convert.ToInt32(st.Element("STRING")
                                                    .Attribute("ID").Value)
                                    Order By ID Ascending
                                    Select New XElement("STRUCT",
                                       New XElement("STRING", st.Element("STRING").Value, 
                                          New XAttribute("ID", ID)))
                                    )
                                )
                            )

答案 1 :(得分:0)

如果你的<OBJECT><CONTENT>层次结构是静态的(没有属性等,需要复制到输出中),那么你可以在一个LINQ查询中使用VB.NET的漂亮支持来做到这一点适用于嵌入式查询的XML literals

Dim origXML =
<OBJECTS>
    <OBJECT>
        <CONTENT>
            <STRUCT>
                <STRING ID="2">string2</STRING>
            </STRUCT>
            <STRUCT>
                <STRING ID="1">string1</STRING>
            </STRUCT>
        </CONTENT>
    </OBJECT>
    <OBJECT>
        <CONTENT>
            <STRUCT>
                <STRING ID="345">string345</STRING>
            </STRUCT>
            <STRUCT>
                <STRING ID="333">string333</STRING>
            </STRUCT>
        </CONTENT>
    </OBJECT>
</OBJECTS>
Dim out = New XDocument(New XElement("OBJECTS",
    From c In origXML...<CONTENT>
    Select _
    <OBJECT>
        <CONTENT>
            <%= From s In c.<STRUCT> Order By CInt(s.<STRING>.@ID) Select s %>
        </CONTENT>
    </OBJECT>
))

out变量将是具有以下内容的XDocument:

<OBJECTS>
    <OBJECT>
        <CONTENT>
            <STRUCT>
                <STRING ID="1">string1</STRING>
            </STRUCT>
            <STRUCT>
                <STRING ID="2">string2</STRING>
            </STRUCT>
        </CONTENT>
    </OBJECT>
    <OBJECT>
        <CONTENT>
            <STRUCT>
                <STRING ID="333">string333</STRING>
            </STRUCT>
            <STRUCT>
                <STRING ID="345">string345</STRING>
            </STRUCT>
        </CONTENT>
    </OBJECT>
</OBJECTS>

如上所述,这是重新创建<OBJECT><CONTENT>元素,因此这些元素的所有属性都将丢失。