问题描述:

I am new to XSLT. Here is what i am trying to do.

I have the below source XML. If the EFFRG Attribute value of EFFECT Element (Child Element of ITEM) starts with RU, then do the following.

1) Replace the EFFRG attribute with EFFTEXT and the value should be "See Restricted Usage"

2) for each RU value of EFFRG insert the below elements before PNIREF element if exists. If doesn't exists then add the elements at the end of the Parent Element.

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

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

Note: i have multiple ITEM element tags which may or may not have PNRIREF tag and all the attribute values of EFFRG doesn't start with 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>

As of now i am here in the xslt transformation.

 <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>

网友答案:

I don't think you need the otherwise branch as it would be covered by the identity transformation template, so move the test into a predicate pattern and then add two templates for the other two checks and have a fourth template for the creation of the new elements, in XSLT 2.0 that results in

<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>
相关阅读:
Top