2016-12-27 146 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工作。 –

相關問題