2017-03-07 3 views
0

Ich versuche, diese Daten zu transformieren:Wie kann nur ein anderer Knoten basierend auf dem Attributwert eines bestimmten Knotens geändert werden?

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

dies zu erhalten:

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

und ich bin derzeit mit dieser 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> 

So, Ich versuche zu:

  1. „eine logische Ebene nach oben“ Elemente <branch type="band/other"> passende <branch type="other"> zu erhalten, während link Attribut Clearing und die Eltern und Geschwister zu verwerfen ->OK

  2. dann für Elemente aus Teil 1 finden <branch type="member"> welche haben link attr. Wert (zB "1") und benennen Sie sie (und ihre branch Kinder) von "-info" auf "member" Wert des Attributs type anhängt ->NOK

  3. andere Elemente halten, wie sie sind ->OK

Probleme mit Teil 2:

  • Original (unrenamed, link = "1") "member/kind" bleibt
  • Original (unrenamed, link = "1") "Mitglied" und Kind "Mitglied/Art" bleiben

Wie kann ich lösen diejenigen? Brauche ich einen anderen Ansatz (mit dem Namen templated)?

Antwort

0

Ich glaube, Sie die Elemente in Vorlagen entsprechen und manipulieren können nur die Attribute:

<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 Mit 3 haben wir die Werte in einer Variablen speichern kann und einen Schlüssel zu verwenden, die referenzierte zu finden Artikel:

<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

Leider habe ich keinen Zugriff auf XSLT 3.0 (obwohl ich veränderbare Variablen seit einiger Zeit will). Trotzdem funktioniert die 2.0-Version einwandfrei. Vielen Dank! – Saran

Verwandte Themen