2017-07-04 2 views
0

Ich muss ein Sub-XML von einigen XML-Datei erstellen. Ich habe eine Liste der erforderlichen Knoten. Wie sollte xslt Transformation aussehen? Zum Beispiel Eingabedatei:xslt Transformation von xml zu xml spezifischen Knoten kopieren omly

<?xml version="1.0"?> 
<root> 
    <a id="A"> 
    <aa>text</aa> 
    <bb>text</bb> 
    <cc id="1"> 
     <aaa>text</aaa> 
     <bbb>text</bbb> 
    </cc> 
    </a> 
    <a id="B"> 
    <aa>text2</aa> 
    <bb>text2</bb> 
    <cc id="2"> 
     <aaa>text2</aaa> 
     <bbb>text2</bbb>  
    </cc> 
    </a> 
</root> 

gewünschte Ausgabe:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <a id="A"> 
     <bb>text</bb> 
     <cc> 
     <bbb>text</bbb> 
     </cc> 
    </a> 
    <a id="B"> 
     <bb>text2</bb> 
     <cc> 
     <bbb>text2</bbb> 
     </cc> 
    </a> 
</root> 

Derzeit verwende ich follwonf Xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > 
    <xsl:output indent="yes"/> 

    <xsl:template match="node()|@*"/> 

    <xsl:template match=" 
root 
|root/a 
|root/a/@id 
|root/a/bb 
|root/a/bb/node() 
|root/a/cc 
|root/a/cc/bbb 
|root/a/cc/bbb/node() 
"> 
    <xsl:copy> 
     <xsl:apply-templates select="node() | @*"/> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

Aber ich möchte kürzer etwas wie diese Liste haben:

root/a/@id 
|root/a/bb/node() 
|root/a/cc/bbb/node() 

Also, wie xslt Transformation für diese kurze Liste zu erstellen?

Antwort

0

Nun, in XSLT 2.0 eine Variable mit diesen Knoten verwenden könnte, die Vorfahren in einer anderen Variablen berechnen und dann diese Variablen verwenden, wie folgt:

<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 indent="yes"/> 

    <xsl:variable name="copy" 
     select=" 
     root/a/@id 
     |root/a/bb/node() 
     |root/a/cc/bbb/node()"/> 

    <xsl:variable name="subtrees" select="$copy/ancestor-or-self::node()"/> 

    <xsl:template match="*[. intersect $subtrees]"> 
     <xsl:copy> 
      <xsl:copy-of select="@*[. intersect $copy]"/>    
      <xsl:apply-templates select="node()[. intersect $subtrees]"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

In XSLT 3.0 eine static parameter und shadow attribute mit konnte man eve n parametrisieren weiter:

<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:param name="paths" static="yes" as="xs:string" 
     select="'root/a/@id | root/a/bb/node() | root/a/cc/bbb/node()'"/> 

    <xsl:output indent="yes"/> 

    <xsl:variable name="copy" _select="{$paths}"/> 

    <xsl:variable name="subtrees" select="$copy/ancestor-or-self::node()"/> 

    <xsl:template match="*[. intersect $subtrees]"> 
     <xsl:copy> 
      <xsl:copy-of select="@*[. intersect $copy]"/>    
      <xsl:apply-templates select="node()[. intersect $subtrees]"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
+0

Danke! Genau das, was ich brauche. Ich weiß nicht, wie diese Magie funktioniert, aber es funktioniert und es ist eine Hauptsache für mich jetzt! – qwerty1222

0

Ich würde bekommen spezifischere:

XSLT

<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="a"> 
    <xsl:copy> 
     <xsl:apply-templates select="@id|bb|cc"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="cc"> 
    <xsl:copy> 
     <xsl:apply-templates select="bbb"/> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 
0

in XSLT 1.0 I würde die folgende Transformation vorzuschlagen:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:template match="@*|node()"> 
    <xsl:if test="not(. = following-sibling::*)"> 
     <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

Sie wählt jeder letzten Knoten weicht identischen Wert hat.

Verwandte Themen