基于子元素属性用XSLT或Python对XML文件排序

基于子元素属性用XSLT或Python对XML文件排序,python,xml,xslt,Python,Xml,Xslt,我有许多XML文件,其结构如下: <titles> <title mode="example" name="name_example"> <titleselect> <attribute_a>attrib_a</attribute_a> <attribute_b>attrib_b</attribute_b> <attribute_c>attrib_c&l

我有许多XML文件,其结构如下:

<titles>
  <title mode="example" name="name_example">
    <titleselect>
      <attribute_a>attrib_a</attribute_a>
      <attribute_b>attrib_b</attribute_b>
      <attribute_c>attrib_c</attribute_c>
      <sort_attribute>New York</sort_attribute>
    </titleselect>
  </title>
  <title mode="another_example" name="another_name">
    <titleselect>
      <attribute_a>attrib_a</attribute_a>
      <attribute_b>attrib_b</attribute_b>
      <attribute_c>attrib_c</attribute_c>
      <sort_attribute>Boston</sort_attribute>
    </titleselect>
  </title>
  <title mode="final_example" name="final_name">
    <titleselect>
      <attribute_a>attrib_a</attribute_a>
      <attribute_b>attrib_b</attribute_b>
      <attribute_c>attrib_c</attribute_c>
      <sort_attribute>Chicago</sort_attribute>
    </titleselect>
  </title>
</titles>


没有用。

如果您仍然对Python解决方案感兴趣,可以使用
ElementTree
实现

工作原理:

  • 获取所有
    标题
    节点
  • 从根节点删除每个节点
  • 根据
    sort\u属性对内存中的
    title
    节点进行排序
  • 将每个
    标题
    节点按正确顺序添加回根元素

  • 产出:

    <titles>
        <title mode="another_example" name="another_name">
            <titleselect>
                <attribute_a>attrib_a</attribute_a>
                <attribute_b>attrib_b</attribute_b>
                <attribute_c>attrib_c</attribute_c>
                <sort_attribute>Boston</sort_attribute>
            </titleselect>
        </title>
        <title mode="final_example" name="final_name">
            <titleselect>
                <attribute_a>attrib_a</attribute_a>
                <attribute_b>attrib_b</attribute_b>
                <attribute_c>attrib_c</attribute_c>
                <sort_attribute>Chicago</sort_attribute>
            </titleselect>
        </title>
        <title mode="example" name="name_example">
            <titleselect>
                <attribute_a>attrib_a</attribute_a>
                <attribute_b>attrib_b</attribute_b>
                <attribute_c>attrib_c</attribute_c>
                <sort_attribute>New York</sort_attribute>
            </titleselect>
        </title>
    </titles>
    
    
    属性
    属性
    属性
    波士顿
    属性
    属性
    属性
    芝加哥
    属性
    属性
    属性
    纽约
    
    作为XSLT的替代方案,根据Tomalek的评论,使用一个模板捕获父
    标题
    ,然后按所需的
    排序属性
    (实际上是一个元素)排序,并复制内部
    标题
    内容,这是相当简单的:

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
      <!-- identity transform -->
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="titles">
        <xsl:copy>
          <xsl:apply-templates select="title">
            <xsl:sort select="titleselect/sort_attribute" data-type="text" order="ascending"/>
          </xsl:apply-templates>
        </xsl:copy>
      </xsl:template>
    </xsl:stylesheet>
    
    
    
    是的,这很简单。你链接到的答案已经很好了,你是如何尝试应用它的?非常感谢,这完全解决了我的问题!我认为match属性是我以前的尝试无法成功的原因。是否要将结果写入新的XML文件?
    <titles>
        <title mode="another_example" name="another_name">
            <titleselect>
                <attribute_a>attrib_a</attribute_a>
                <attribute_b>attrib_b</attribute_b>
                <attribute_c>attrib_c</attribute_c>
                <sort_attribute>Boston</sort_attribute>
            </titleselect>
        </title>
        <title mode="final_example" name="final_name">
            <titleselect>
                <attribute_a>attrib_a</attribute_a>
                <attribute_b>attrib_b</attribute_b>
                <attribute_c>attrib_c</attribute_c>
                <sort_attribute>Chicago</sort_attribute>
            </titleselect>
        </title>
        <title mode="example" name="name_example">
            <titleselect>
                <attribute_a>attrib_a</attribute_a>
                <attribute_b>attrib_b</attribute_b>
                <attribute_c>attrib_c</attribute_c>
                <sort_attribute>New York</sort_attribute>
            </titleselect>
        </title>
    </titles>
    
    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
      <!-- identity transform -->
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="titles">
        <xsl:copy>
          <xsl:apply-templates select="title">
            <xsl:sort select="titleselect/sort_attribute" data-type="text" order="ascending"/>
          </xsl:apply-templates>
        </xsl:copy>
      </xsl:template>
    </xsl:stylesheet>