How to get row numbers for elements of XML, using XSLT?

梦想与她 提交于 2020-01-07 03:25:08

问题


Input XML:

  <root>
    <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>
        <changedName>
            <languageCode colNumber="4">fd777r</languageCode>
            <languageCode colNumber="4">fr777</languageCode>
            <dummy colNumber="5">DDD777UMM</dummy>
        </changedName>
    </imageLink>
</root>

Expected XML output:

 <?xml version="1.0" encoding="UTF-8"?>
<root>
    <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>
        <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>
    </imageLink>
</root>

this process happens in multiple levels of element complexity, these row numbers are assigned so that it enters into an excel sheet in the form of rows and columns

can anyone please assist me?


回答1:


I am not sure why the edit removed the XSLT 2.0 tag but as a follow-up to the earlier problem with two levels of nesting I post this XSLT 2.0 stylesheet that should work with three levels of nesting:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

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

    <xsl:template match="root">
        <xsl:copy>
            <xsl:apply-templates select="*[1]"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="root//*[*]">
        <xsl:param name="row" select="1"/>
        <xsl:variable name="copy" as="element()">
            <xsl:copy>
                <xsl:attribute name="rowNum" select="$row"/>
                <xsl:apply-templates select="*[1]">
                    <xsl:with-param name="row" select="$row"/>
                </xsl:apply-templates>
            </xsl:copy>
        </xsl:variable>
        <xsl:copy-of select="$copy"/>
        <xsl:apply-templates select="following-sibling::*[1]">
            <xsl:with-param name="row" select="max($copy/descendant-or-self::*[@rowNum]/@rowNum) + 1"/>
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="root/*//*[not(*)]">
        <xsl:param name="row"/>
        <xsl:variable name="index" as="xs:integer">
            <xsl:number/>
        </xsl:variable>
        <xsl:variable name="copy" as="element()">
            <xsl:copy>
                <xsl:attribute name="rowNum" select="$row - 1 + $index"/>
                <xsl:copy-of select="@*, node()"/>
            </xsl:copy>         
        </xsl:variable>
        <xsl:copy-of select="$copy"/>
        <xsl:apply-templates select="following-sibling::*[1]">
            <xsl:with-param name="row" select="$row"/>
        </xsl:apply-templates>
    </xsl:template>

</xsl:stylesheet>


来源:https://stackoverflow.com/questions/41606461/how-to-get-row-numbers-for-elements-of-xml-using-xslt

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!