2017-03-07 119 views
0

我試圖改變這樣的數據:如何僅基於特定節點的屬性值修改其他節點?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<root> 
    <branch link="1" type="band" value=""> 
    <leaf/> 
    <branch link="1" type="band/mhz" value="some"> 
     <leaf/> 
    </branch> 
    <branch link="1" type="band/other" value="thing"> 
     <leaf/> 
    </branch> 
    </branch> 
    <branch link="1" type="member" value=""> 
    <leaf/> 
    <branch link="1" type="member/kind" value="a"> 
     <leaf/> 
    </branch> 
    </branch> 
    <branch link="2" type="member" value=""> 
    <leaf/> 
    <branch link="2" type="member/kind" value="b"> 
     <leaf/> 
    </branch> 
    </branch> 
</root> 

得到這個:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<root> 
    <branch link="" type="other" value="thing"> 
    <leaf/> 
    </branch> 
    <branch link="" type="member-info" value=""> 
    <leaf/> 
    <branch link="" type="member-info/kind" value="a"> 
     <leaf/> 
    </branch> 
    </branch> 
    <branch link="2" type="member" value=""> 
    <leaf/> 
    <branch link="2" type="member/kind" value="b"> 
     <leaf/> 
    </branch> 
    </branch> 
</root> 

,目前我使用這個XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

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

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

    <xsl:template match="branch[starts-with(@name, 'band')]"> 

    <xsl:for-each select="current()/*"> 
     <xsl:if test="@name = 'band/other'"> 
     <xsl:variable name="linkId" select="@link"/> 

     <xsl:for-each select="../../branch[@link=$linkId and @name='member']"> 
      <branch> 
      <xsl:attribute name="name"> 
       <xsl:value-of select="replace(@name, 'member', 'member-info')"/> 
      </xsl:attribute> 
      <xsl:for-each select="@*[.]"> 
       <xsl:if test="local-name() != 'name'"> 
       <xsl:attribute name="{local-name()}"> 
        <xsl:if test="local-name() != 'link'"> 
        <xsl:value-of select="."/> 
        </xsl:if> 
       </xsl:attribute> 
       </xsl:if> 
      </xsl:for-each> 

      <xsl:for-each select="./*"> 
       <branch> 
       <xsl:attribute name="name"> 
        <xsl:value-of 
        select="replace(@name, 'member', 'member-info')"/> 
        </xsl:attribute> 
        <xsl:for-each select="@*[.]"> 
        <xsl:if test="local-name() != 'name'"> 
         <xsl:attribute name="{local-name()}"> 
         <xsl:if test="local-name() != 'link'"> 
          <xsl:value-of select="."/> 
         </xsl:if> 
         </xsl:attribute> 
        </xsl:if> 
        </xsl:for-each> 
        <xsl:apply-templates/> 
       </branch> 
       </xsl:for-each> 
      </branch> 
      <xsl:apply-templates/> 
      </xsl:for-each> 

      <xsl:copy> 
      <xsl:attribute name="name"> 
       <xsl:value-of select="replace(@name, 'band/', '')"/> 
      </xsl:attribute> 
      <xsl:for-each select="@*[.]"> 
       <xsl:if test="local-name() != 'name'"> 
       <xsl:attribute name="{local-name()}"> 
        <xsl:if test="local-name() != 'link'"> 
        <xsl:value-of select="."/> 
        </xsl:if> 
       </xsl:attribute> 
       </xsl:if> 
      </xsl:for-each> 
      <xsl:apply-templates/> 
      </xsl:copy> 
     </xsl:if> 
     </xsl:for-each> 

    </xsl:template> 

    <xsl:template match="branch[@name='member' and @link='']"/> 

    </xsl:stylesheet> 

所以,我試圖:

  1. 「動起來邏輯電平」的元素匹配<branch type="band/other">得到<branch type="other">在清除link屬性和丟棄的父母和兄弟姐妹 - >OK

  2. 然後,從第1部分元素,找到<branch type="member">其中有相同的link屬性。值(例如「1」)和通過將「-info」屬性的爲「構件」值重命名它們(以及它們的branch子女)type - >NOK

  3. 保持其它元素,因爲它們是 - >

問題與第2部分:

  • 原始(unrenamed,鏈接= 「1」) 「部件/一種」 保持
  • 原(unrenamed,鏈接= 「1」) 「成員」 和兒童 「成員/一種」 保持

我怎樣才能解決這些?我是否需要一種不同的方法(使用名爲tempalted)?

回答

0

我想你可以匹配在模板中的元素,只是操作的屬性:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 

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

    <xsl:template match="branch[.//branch[@type = 'band/other']]"> 
     <xsl:apply-templates select=".//branch[@type = 'band/other']"/> 
    </xsl:template> 

    <xsl:template match="branch[@type = 'band/other']/@type"> 
     <xsl:attribute name="type" select="replace(., 'band/', '')"/> 
    </xsl:template> 

    <xsl:template match="branch[@type = 'band/other']/@link | branch[@type[starts-with(., 'member')] and @link = //branch[@type = 'band/other']/@link]/@link"> 
     <xsl:attribute name="link"></xsl:attribute> 
    </xsl:template> 

    <xsl:template match="branch[@type[starts-with(., 'member')] and @link = //branch[@type = 'band/other']/@link]/@type"> 
     <xsl:attribute name="member" select="replace(., 'member', 'member-info')"/> 
    </xsl:template> 
</xsl:transform> 

http://xsltransform.net/94AbWC3/1

使用XSLT 3,我們可以存儲值的變量,並使用一鍵查找引用項目:

<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="3.0"> 

    <xsl:variable name="change" select="//branch[@type = 'band/other']"/> 

    <xsl:key name="ref" match="branch[@type[starts-with(., 'member')]]" use="@link"/> 

    <xsl:variable name="change-ref" select="key('ref', $change/@link)"/> 

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

    <xsl:template match="branch[.//branch[@type = 'band/other']]"> 
     <xsl:apply-templates select=".//branch[@type = 'band/other']"/> 
    </xsl:template> 

    <xsl:template match="$change/@type"> 
     <xsl:attribute name="type" select="replace(., 'band/', '')"/> 
    </xsl:template> 

    <xsl:template match="$change/@link | $change-ref/@link"> 
     <xsl:attribute name="link"></xsl:attribute> 
    </xsl:template> 

    <xsl:template match="$change-ref/@type"> 
     <xsl:attribute name="member" select="replace(., 'member', 'member-info')"/> 
    </xsl:template> 

</xsl:stylesheet> 
+0

不幸的是,我沒有訪問XSLT 3.0(雖然我一直想變化一段時間的變化)。儘管如此,2.0版本完美運作。謝謝! – Saran

相關問題