如何在多个复杂和重复的层次上使用XSLT获取XML元素的行号?

时间:2017-01-12 13:07:32

标签: xml xslt xslt-1.0 xslt-2.0

我有如下输入:

<root>
    <image>
        <imag1 ></imag1>
        <imag1 ></imag1>
        <imag2 ></imag2>
    <imageLink>
        <url colNumber="1">aa</url>
        <imageTypeCode colNumber="2">PRODUCT_IMAGE</imageTypeCode>
        <languageCode colNumber="3">en</languageCode>
        <languageCode colNumber="3">fr</languageCode>
    </imageLink>
    <imageLink>
        <url colNumber="1">bb</url>
        <imageTypeCode colNumber="2">PRODUCT_IMAGE</imageTypeCode>
        <languageCode colNumber="3">fr</languageCode>
        <commTest>
            <languageCode colNumber="4">fssdr</languageCode>
            <languageCode colNumber="4">fr</languageCode>
            <dummy colNumber="5">DDDUMM</dummy>
        </commTest>
        <commTest>
            <languageCode colNumber="4">fd777r</languageCode>
            <languageCode colNumber="4">fr777</languageCode>
            <dummy colNumber="5">DDD777UMM</dummy>
        </commTest>
    </imageLink>
    <changedName>
            <languageCode colNumber="4">fd777r</languageCode>
            <languageCode colNumber="4">fr777</languageCode>
            <dummy colNumber="5">DDD777UMM</dummy>
        </changedName>
        <changedName>
            <languageCode colNumber="4">fd777r</languageCode>
            <languageCode colNumber="4">fr777</languageCode>
            <dummy colNumber="5">DDD777UMM</dummy>
        </changedName>
    </image>
</root>

我的输出要求如下:

 <?xml version="1.0" encoding="UTF-8"?>
<image rowNum="1">
   <imag1 rowNum="1"/>
   <imag1 rowNum="2"/>
   <imag2 rowNum="1"/>
   <imageLink rowNum="1">
      <url rowNum="1" colNumber="1">aa</url>
      <imageTypeCode rowNum="1" colNumber="2">PRODUCT_IMAGE</imageTypeCode>
      <languageCode rowNum="1" colNumber="3">en</languageCode>
      <languageCode rowNum="2" colNumber="3">fr</languageCode>
   </imageLink>
   <imageLink rowNum="3">
      <url rowNum="3" colNumber="1">bb</url>
      <imageTypeCode rowNum="3" colNumber="2">PRODUCT_IMAGE</imageTypeCode>
      <languageCode rowNum="3" colNumber="3">fr</languageCode>
      <commTest rowNum="3">
         <languageCode rowNum="3" colNumber="4">fssdr</languageCode>
         <languageCode rowNum="4" colNumber="4">fr</languageCode>
         <dummy rowNum="3" colNumber="5">DDDUMM</dummy>
      </commTest>
      <commTest rowNum="5">
         <languageCode rowNum="5" colNumber="4">fd777r</languageCode>
         <languageCode rowNum="6" colNumber="4">fr777</languageCode>
         <dummy rowNum="5" colNumber="5">DDD777UMM</dummy>
      </commTest>
   </imageLink>
   <changedName rowNum="1">
      <languageCode rowNum="1" colNumber="4">fd777r</languageCode>
      <languageCode rowNum="2" colNumber="4">fr777</languageCode>
      <dummy rowNum="1" colNumber="5">DDD777UMM</dummy>
   </changedName>
   <changedName rowNum="3">
      <languageCode rowNum="3" colNumber="4">fd777r</languageCode>
      <languageCode rowNum="4" colNumber="4">fr777</languageCode>
      <dummy rowNum="3" colNumber="5">DDD777UMM</dummy>
   </changedName>
</image>

此过程在元素复杂度的多个级别中发生,这些行号被分配,以便以行和列的形式进入Excel工作表

任何人都可以帮助我吗?

1 个答案:

答案 0 :(得分:0)

根据任何模式中的编号尝试以下XSLT:

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

    <!-- To omit root node -->
    <xsl:template match="root">
        <xsl:apply-templates select="image"/>
    </xsl:template>

    <!-- All other elements -->
    <xsl:template match="*">
        <!-- Depth level -->
        <xsl:variable name="lvl" select="count(ancestor::*) - 1"/>
        <!-- Name of the current node -->
        <xsl:variable name="currName" select="name()"/>
        <!-- Name of the ancestor for numeration -->
        <xsl:variable name="ancName">
            <!-- Children of image - just 'image' -->
            <xsl:if test="$lvl &lt;= 1">
                <xsl:value-of select="'image'"/>
            </xsl:if>
            <!-- "Deeper" descendants - one level deeper -->
            <xsl:if test="$lvl &gt; 1">
                <xsl:value-of select="ancestor::*[$lvl - 1]/name()"/>
            </xsl:if>
        </xsl:variable>
        <!-- Create element with current name -->
        <xsl:element name="{$currName}">
            <!-- Set rowNum -->
            <xsl:attribute name="rowNum">
                <xsl:number level="any" from="*[name()=$ancName]"/>
            </xsl:attribute>
            <!-- Process inner content -->
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

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

您的样本的数字有点不同,但是:

  1. 从您需要的输出示例中,我看到 image 的直接子项 使用相同的名称在整个输出中获得连续的数字。

  2. 正如您在开头的评论中所述,只要有变化...... rowNum 对于图像的直接子项的所有后代应该从1获得数字(在具有相同名称的节点组内单独计数)。