重命名元素的XSLT排序

时间:2016-05-13 14:01:41

标签: xml xslt

我有以下XML:

<order-information>
    <orderRecord>
        <order>
            <num_items>1</num_items>
            <orderNo>CA79268</orderNo>
            <ordDate>20160509</ordDate>
            <colorCode>YEL</colorCode>
            <sizeNo>LG</sizeNo>
            <ordRemarks />
            <catalogNo>00407</catalogNo>
        </order>
        <order>
            <num_items>1</num_items>
            <orderNo>CA79268</orderNo>
            <ordDate>20160509</ordDate>
            <colorCode>BLU</colorCode>
            <sizeNo>SM</sizeNo>
            <ordRemarks />
            <catalogNo>00424</catalogNo>
        </order>
        <order>
            <num_items>1</num_items>
            <orderNo>CA79268</orderNo>
            <ordDate>20160509</ordDate>
            <colorCode>GRN</colorCode>
            <sizeNo />
            <ordRemarks />
            <catalogNo>00499</catalogNo>
        </order>
    </orderRecord>
</order-information>

我需要重命名大多数元素名称,然后按新元素名称对<order>子元素进行排序,以便在第二个应用程序中使用。我还需要添加两个空元素。我无法控制源xml中元素的顺序。我的XSLT尝试(因为方法和示例而仔细阅读此站点的结果):

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

    <xsl:template match="text()">
        <xsl:value-of select="normalize-space(.)"/>
    </xsl:template>

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

    <!-- Order Record -->
    <xsl:template match ="orderRecord/order">
        <xsl:element name="Group">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="order/catalogNo">
        <xsl:element name="V1">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
        <!-- Add empty "V2" and "V3" -->
        <V2/>
        <V3/>
    </xsl:template>
    <xsl:template match="order/num_items">
        <xsl:element name="V4">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="order/orderNo">
        <xsl:element name="V5">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="order/ordDate">
        <xsl:element name="V6">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="order/colorCode">
        <xsl:element name="V7">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="order/sizeNo">
        <xsl:element name="V8">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="order/ordRemarks">
        <xsl:element name="V9">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>

</xsl:transform>

结果:

    <?xml version="1.0" encoding="UTF-8"?>
<order-information>
  <orderRecord>
    <Group>
      <V4>1</V4>
      <V5>CA79268</V5>
      <V6>20160509</V6>
      <V7>YEL</V7>
      <V8>LG</V8>
      <V9/>
      <V1>00407</V1>
      <V2/>
      <V3/>
    </Group>
    <Group>
      <V4>1</V4>
      <V5>CA79268</V5>
      <V6>20160509</V6>
      <V7>BLU</V7>
      <V8>SM</V8>
      <V9/>
      <V1>00424</V1>
      <V2/>
      <V3/>
    </Group>
    <Group>
      <V4>1</V4>
      <V5>CA79268</V5>
      <V6>20160509</V6>
      <V7>GRN</V7>
      <V8/>
      <V9/>
      <V1>00499</V1>
      <V2/>
      <V3/>
    </Group>
  </orderRecord>
</order-information>

但是第二个应用程序需要按以下顺序输入信息:

    <?xml version="1.0" encoding="UTF-8"?>
<order-information>
  <orderRecord>
    <Group>
      <V1>00407</V1>
      <V2/>
      <V3/>
      <V4>1</V4>
      <V5>CA79268</V5>
      <V6>20160509</V6>
      <V7>YEL</V7>
      <V8>LG</V8>
      <V9/>
    </Group>
    <Group>
      <V1>00424</V1>
      <V2/>
      <V3/>
      <V4>1</V4>
      <V5>CA79268</V5>
      <V6>20160509</V6>
      <V7>BLU</V7>
      <V8>SM</V8>
      <V9/>
    </Group>
    <Group>
      <V1>00499</V1>
      <V2/>
      <V3/>
      <V4>1</V4>
      <V5>CA79268</V5>
      <V6>20160509</V6>
      <V7>GRN</V7>
      <V8/>
      <V9/>
    </Group>
  </orderRecord>
</order-information>

实际上,我只需要重命名&#34; catalogNo&#34; as&#34; V1&#34;并移动,使其成为每个&#34;顺序中的第一个元素&#34;节点然后添加空元素&#34; V2&#34;和&#34; V3。&#34;所有其他元素都按正确的顺序排列:

XSLT中是否有一种机制可以按元素的新名称或其他方法排序,以便按照我的第二个应用程序所需的顺序获取我的信息?

感谢。

1 个答案:

答案 0 :(得分:0)

选项1

您可以通过手动匹配order的子项来强制它,如下所示:

<!-- Order Record -->
<xsl:template match ="orderRecord/order">
    <xsl:element name="Group">
        <xsl:apply-templates select="catalogNo"/> <!-- becomes V1, V2, V3 -->
        <xsl:apply-templates select="num_items"/> <!-- becomes V4 -->
        <xsl:apply-templates select="orderNo"/>   <!-- becomes V5 -->
        <xsl:apply-templates select="ordDate"/>   <!-- becomes V6 -->
        <!-- and so on -->
    </xsl:element>
</xsl:template>

选项2

如果你真的需要排序而不是这样一个手工制作的解决方案,第二遍可能也很有趣。我的意思是:保留V*标签未分类,然后运行第二个XSLT表,其唯一目的是对所述标签进行排序。

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

  <xsl:output method="xml" indent="yes" version="1.0" encoding="UTF-8"/>

  <xsl:template match="text()">
    <xsl:value-of select="normalize-space(.)"/>
  </xsl:template>

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

  <!-- Sort Group's children -->
  <xsl:template match="Group">
    <xsl:apply-templates select="*">
      <xsl:sort select="name()"/>
    </xsl:apply-templates>
  </xsl:template>

</xsl:transform>