当父元素具有某个具有特定值的特定属性的其他子元素时,将子元素添加到父元素

时间:2016-12-27 15:59:02

标签: xml xslt

我是XSLT的新手。这是我想要做的。

我有以下源XML。如果EFFECT元素(ITEM的子元素)的EFFRG属性值以RU开头,则执行以下操作。

1)用EFFTEXT替换EFFRG属性,值应为“See Restricted Usage” 2)对于EFFRG的每个RU值,如果存在,则在PNIREF元素之前插入以下元素。如果不存在,则在父元素的末尾添加元素。

    <UOAMFR><UOA>RU320A</UOA></UOAMFR>
    <UOAMFR><UOA>RU320B</UOA></UOAMFR>

注意:我有多个ITEM元素标签,可能有也可能没有PNRIREF标签,EFFRG的所有属性值都不以RU开头。

    Source XML:

    <ITEM CHAPNBR="25" SECTNBR="13" UNITNBR="01" FIGNBR="36J" ITEMNBR="325"
    ILLUSIND="0" INDENT="3" ATTACH="0" CHG="U" KEY="ITA300-600IPCFX125130136J325"
    REVDATE="20081201">
    <EFFECT EFFRG="RU320A RU320B"/>
    <PNRMFR>
    <PNR>NAS1836-08-07M</PNR>
    <MFR>80205</MFR>
    </PNRMFR>
    <UPA>020</UPA>
    <TQA>0020</TQA>
    <ADT>INSERT</ADT>
    <PNRIREF HREF="www.example.com"/>
    </ITEM>

    Transformed XML:

    <ITEM CHAPNBR="25" SECTNBR="13" UNITNBR="01" FIGNBR="36J" ITEMNBR="325"
    ILLUSIND="0" INDENT="3" ATTACH="0" CHG="U" KEY="ITA300-600IPCFX125130136J325"
    REVDATE="20081201">
    <EFFECT EFFTEXT="See Restricted Usage"/>
    <PNRMFR>
    <PNR>NAS1836-08-07M</PNR>
    <MFR>80205</MFR>
    </PNRMFR>
    <UPA>020</UPA>
    <TQA>0020</TQA>
    <ADT>INSERT</ADT>
    <UOAMFR><UOA>RU320A</UOA></UOAMFR>
    <UOAMFR><UOA>RU320B</UOA></UOAMFR>
    <PNRIREF HREF="www.example.com"/>
    </ITEM>

截至目前,我正在进行xslt转换。

    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output omit-xml-declaration="yes" indent="yes"/>
        <xsl:strip-space elements="*"/>

        <xsl:template match="ITEM/EFFECT/@EFFRG">
            <xsl:choose>
                <xsl:when test="starts-with(.,'RU')">
                    <xsl:attribute name="EFFTEXT">
                        <xsl:text>See Restricted Usage</xsl:text>
                    </xsl:attribute>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:attribute name="EFFRG">
                    <xsl:value-of select="." />
                    </xsl:attribute>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template>

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

1 个答案:

答案 0 :(得分:1)

我认为您不需要身份转换模板所涵盖的otherwise分支,因此请将测试转换为谓词模式,然后为其他两个检查添加两个模板,并且用于创建新元素的第四个模板,在XSLT 2.0中导致

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    exclude-result-prefixes="xs math"
    version="2.0">

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

    <xsl:template match="ITEM/EFFECT/@EFFRG[starts-with(., 'RU')]">
        <xsl:attribute name="EFFTEXT">See Restricted Usage</xsl:attribute>
    </xsl:template>

    <xsl:template name="eff">
        <xsl:for-each select="tokenize(../EFFECT/@EFFRG, '\s+')">
            <UOAMFR>
                <UOA>
                    <xsl:value-of select="."/>
                </UOA>
            </UOAMFR>
        </xsl:for-each>     
    </xsl:template>

    <xsl:template match="ITEM[EFFECT/@EFFRG[starts-with(., 'RU')] and not(PNRIREF)]/*[position() = last()]">
        <xsl:copy-of select="."/>
        <xsl:call-template name="eff"/>
    </xsl:template>

    <xsl:template match="ITEM[EFFECT/@EFFRG[starts-with(., 'RU')]]/PNRIREF">
        <xsl:call-template name="eff"/>
        <xsl:copy-of select="."/>
    </xsl:template>

</xsl:stylesheet>