2017-07-04 31 views
0

我需要創建一些xml文件的子xml。 我有一個所需節點的列表。 xslt tranformation應該如何看起來像? 例如,輸入文件:xslt轉換從xml複製到xml特定節點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> 

所需的輸出:

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

目前我使用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> 

但我想有名單的東西更短的那樣:

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

那麼如何爲這個短列表創建xslt轉換呢?

回答

0

那麼,在XSLT 2.0中,您可以用與這些節點的變量,計算祖先在另一個變量,然後使用這些變量如下:

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

在XSLT 3.0使用static parametershadow attribute你可以前夜n個其它參數它:

<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

謝謝!正是我需要的。我不知道這個魔法是如何運作的,但它是有效的,現在它對我來說是主要的東西! – qwerty1222

0

我會得到更具體:

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

在XSLT 1.0我建議以下變換:

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

它選擇每一個最後的節點至極具有相同的值。