2017-03-23 3 views
0

Ich muss zwei Attribute eines Knotens basierend auf dem Wert von einem von ihnen ändern. Wenn @ dc = "R" und @ rt = "UM", dann muss ich @dc zu "NF" ändern und das @rt-Attribut entfernen. Hier ist, wie ich versucht habe, es zu tun, aber das löscht alle Unterelemente des Dokuments.Ändern von zwei Attributen mit XSLT

Beispieldokument:

<?xml version="1.0" encoding="UTF-8"?> 
<ID dc="R" rt="UM" other="attr"> 
    <foo>bar</foo> 
</ID> 

Sheet:

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

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

<xsl:template match="*[@dc = 'R' and @rt = 'UM']"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()" mode="nf"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="@dc" mode="nf"> 
    <xsl:attribute name="dc"> 
     <xsl:text>NF</xsl:text> 
    </xsl:attribute> 
</xsl:template> 

<xsl:template match="@rt" mode="nf"/> 

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

</xsl:stylesheet> 

Ergebnis:

<?xml version="1.0" encoding="UTF-8"?> 
<ID dc="NF" other="attr"/> 

Der <foo>-Tag und sein Text verschwunden sind. Gibt es einen besseren Weg? Fehle ich etwas?

+0

Ihre zweite Vorlage hat 'node' statt' Knoten() '. Und Sie sollten den Modus wahrscheinlich auch in der letzten Vorlage zu "xsl: apply-templates" hinzufügen. Obwohl ich nicht denke, dass Sie den Modus überhaupt verwenden müssen. –

Antwort

1

Wenn @ dc = "R" und @ rt = "UM" dann muss ich @dc auf "NF" ändern und das @rt Attribut entfernen.

Könnten Sie nicht einfach tun:

XSLT 1,0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="@dc[.='R' and ../@rt='UM']"> 
    <xsl:attribute name="dc">NF</xsl:attribute> 
</xsl:template> 

<xsl:template match="@rt[.='UM' and ../@dc='R']" /> 

</xsl:stylesheet> 

Oder, wenn Sie bevorzugen:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="*[@dc='R' and @rt='UM']"> 
    <xsl:copy> 
     <xsl:attribute name="dc">NF</xsl:attribute> 
     <xsl:apply-templates select="@*[not(name()='dc' or name()='rt')] | node()"/> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 
+0

Funktioniert das? Wird nicht eine der Vorlagen das Attribut ändern, sodass die andere nicht übereinstimmt? – Derek

+0

@Derek Eine Vorlage entspricht dem Attribut "dc" und ändert es. Eine andere Vorlage entspricht dem Attribut 'rt' und unterdrückt es. Hier gibt es keinen Konflikt. Beachten Sie, dass beide Vorlagen ein * Prädikat * in ihren Übereinstimmungsmustern haben, um sicherzustellen, dass sie nur funktionieren, wenn die beiden Bedingungen erfüllt sind. Andernfalls wird die Vorlage * identity transform * übernommen und kopiert alles wie es ist. –

+0

In Ihrem ersten Beispiel, lassen Sie uns sagen, die erste Vorlage trifft, ändert sich '@ dc' in NF, wird das dann nicht dazu führen, dass das Prädikat' @ dc = 'R'' fehlt? – Derek

1

Vielleicht XSLT Sie hilft:

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

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

    <xsl:template match="ID[@dc = 'R' and @rt = 'UM']">   <!-- replaces the matching ID nodes with the desired output --> 
     <xsl:element name="ID"> 
      <!-- copies all attributes of the current ID node except 'dc' --> 
      <xsl:apply-templates select="@*[local-name() != 'dc']" /> 
      <!-- sets the attribute to the desired value 'NF' -->     
      <xsl:attribute name="dc">NF</xsl:attribute> 
      <!-- applies the rest of the templates --> 
      <xsl:apply-templates /> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

Ausgang ist:

<?xml version="1.0"?> 
<ID rt="UM" other="attr" dc="NF"> 
    <foo>bar</foo> 
</ID> 
-2
<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs" 
    version="2.0"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="ID"> 
     <ID> 
      <xsl:apply-templates select="@* except @rt"/> 
      <xsl:if test="normalize-space(@dc)"> 
       <xsl:attribute name="NF" select="@dc"/> 

      </xsl:if> 

      <xsl:apply-templates/> 

     </ID> 
    </xsl:template> 

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