基于最内层的孩子对复杂的XML进行排序

时间:2018-02-13 08:34:18

标签: c# xml

我有一个包含数据的XML文件,如下所示 -

<?xml version="1.0" encoding="utf-8"?>
<Root>
  <RootInner>
    <NodesMain>
      <Main>
        <Modules>
          <Module>
            <Description>
              <Child>
                <Descriptionettings>
                  <setting name="ChildId" value="22" />
                  <setting name="ChildName" value="Child_1" />
                  <setting name="Capacity" value="100" />
                  <setting name="ChildType" value="DefaultChild" />
                </Descriptionettings>
              </Child>
              <Child>
                <Descriptionettings>
                  <setting name="ChildId" value="33" />
                  <setting name="ChildName" value="Reject" />
                  <setting name="Capacity" value="200" />
                  <setting name="ChildType" value="Reject" />
                </Descriptionettings>
              </Child>
            </Description>
            <Header>
              <setting name="ModuleName" value="CC" />
              <setting name="ModuleType" value="CC" />
              <setting name="ModulePosition" value="3" />
            </Header>
          </Module>
          <Module>
            <Description>
              <Child>
                <Descriptionettings>
                  <setting name="ChildId" value="19" />
                  <setting name="ChildName" value="Child_1" />
                  <setting name="Capacity" value="100" />
                  <setting name="ChildType" value="DefaultChild" />
                </Descriptionettings>
              </Child>
              <Child>
                <Descriptionettings>
                  <setting name="ChildId" value="18" />
                  <setting name="ChildName" value="Reject" />
                  <setting name="Capacity" value="200" />
                  <setting name="ChildType" value="Reject" />
                </Descriptionettings>
              </Child>
            </Description>
            <Header>
              <setting name="ModuleName" value="AA" />
              <setting name="ModuleType" value="AA" />
              <setting name="ModulePosition" value="1" />
            </Header>
          </Module>
          <Module>
            <Description>
              <Child>
                <Descriptionettings>
                  <setting name="ChildId" value="OC11" />
                  <setting name="ChildName" value="OC11" />
                  <setting name="Capacity" value="100" />
                  <setting name="ChildType" value="SDMChild" />
                </Descriptionettings>
              </Child>
              <Child>
                <Descriptionettings>
                  <setting name="ChildId" value="OC14" />
                  <setting name="ChildName" value="OC14" />
                  <setting name="Capacity" value="100" />
                  <setting name="ChildType" value="SDMChild" />
                </Descriptionettings>
              </Child>
            </Description>
            <Header>
              <setting name="ModuleName" value="BB" />
              <setting name="ModuleType" value="BB" />
              <setting name="ModulePosition" value="2" />
            </Header>
          </Module>
        </Modules>
      </Main>
    </NodesMain>
  </RootInner>
</Root>

我想通过C#.Net中的“ModulePosition”对元素进行排序。最终输出应如下。我试过的示例代码发布在下面

<Root>
  <RootInner>
    <NodesMain>
      <Main>
        <Modules>
          <Module>
            <Description>
              <Child>
                <Descriptionettings>
                  <setting name="ChildId" value="19" />
                  <setting name="ChildName" value="Child_1" />
                  <setting name="Capacity" value="100" />
                  <setting name="ChildType" value="DefaultChild" />
                </Descriptionettings>
              </Child>
              <Child>
                <Descriptionettings>
                  <setting name="ChildId" value="18" />
                  <setting name="ChildName" value="Reject" />
                  <setting name="Capacity" value="200" />
                  <setting name="ChildType" value="Reject" />
                </Descriptionettings>
              </Child>
            </Description>
            <Header>
              <setting name="ModuleName" value="AA" />
              <setting name="ModuleType" value="AA" />
              <setting name="ModulePosition" value="1" />
            </Header>
          </Module>
          <Module>
            <Description>
              <Child>
                <Descriptionettings>
                  <setting name="ChildId" value="OC11" />
                  <setting name="ChildName" value="OC11" />
                  <setting name="Capacity" value="100" />
                  <setting name="ChildType" value="SDMChild" />
                </Descriptionettings>
              </Child>
              <Child>
                <Descriptionettings>
                  <setting name="ChildId" value="OC14" />
                  <setting name="ChildName" value="OC14" />
                  <setting name="Capacity" value="100" />
                  <setting name="ChildType" value="SDMChild" />
                </Descriptionettings>
              </Child>
            </Description>
            <Header>
              <setting name="ModuleName" value="BB" />
              <setting name="ModuleType" value="BB" />
              <setting name="ModulePosition" value="2" />
            </Header>
          </Module>
          <Module>
            <Description>
              <Child>
                <Descriptionettings>
                  <setting name="ChildId" value="22" />
                  <setting name="ChildName" value="Child_1" />
                  <setting name="Capacity" value="100" />
                  <setting name="ChildType" value="DefaultChild" />
                </Descriptionettings>
              </Child>
              <Child>
                <Descriptionettings>
                  <setting name="ChildId" value="33" />
                  <setting name="ChildName" value="Reject" />
                  <setting name="Capacity" value="200" />
                  <setting name="ChildType" value="Reject" />
                </Descriptionettings>
              </Child>
            </Description>
            <Header>
              <setting name="ModuleName" value="CC" />
              <setting name="ModuleType" value="CC" />
              <setting name="ModulePosition" value="3" />
            </Header>
          </Module>
        </Modules>
      </Main>
    </NodesMain>
  </RootInner>
</Root>

我正在使用XDocument加载内容和orderby linq表达式进行排序。但结果不准确,示例代码如下

var documents2 = xDoc.Descendants("Module").OrderBy(x => (int)(x.Elements("attribute").First().Attribute("value"))).ToList();

1 个答案:

答案 0 :(得分:0)

使用XSLT,您可以按如下方式对Module元素的Modules子元素进行排序:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Modules">
      <xsl:copy>
          <xsl:apply-templates select="Module">
              <xsl:sort select="Header/setting[@name = 'ModulePosition']/@value" data-type="number"/>
          </xsl:apply-templates>
      </xsl:copy>
  </xsl:template>


</xsl:stylesheet>

http://xsltfiddle.liberty-development.net/948Fn5h

使用LINQ和C#,您可以使用

        XDocument doc = XDocument.Load("input.xml");

        foreach (XElement modules in doc.Descendants("Modules"))
        {
            modules.ReplaceNodes(
                modules
                .Elements("Module")
                .OrderBy(m => (int)m.Element("Header").Elements("setting").First(s => (string)s.Attribute("name") == "ModulePosition").Attribute("value")).ToList()
                );
        }

        doc.Save("output.xml");