2016-12-27 147 views
0

我是XSLT新手。这是我想要做的。向父元素添加一个子元素,当父元素具有某个具有某个值的某个属性的其他子元素时

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

1)将EFFRG属性替换为EFFTEXT,并且该值应为“参见受限使用” 2)对于EFFRG的每个RU值,如果存在,则在PNIREF元素之前插入以下元素。如果不存在,则在父元素的末尾添加元素。

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

注:我有可能会或可能不会有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

您可以使用XSLT 2.0处理器一样撒克逊9,XmlPrime或Altova的?在XSLT 2.0中使用'tokenize'很容易分解'RU320A RU320B'的值。 –

回答

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

谢谢Martin Honnen。你的XSLT工作。 –

相关问题