2014-04-06 122 views
0

我想使用XSLT展平XML文件。例(有可能是任何數量的nodeedge節點):XSLT轉換:基於其屬性值展平嵌套節點

輸入:

<?xml version="1.0" encoding="utf-8"?> 
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"> 
    <graph> 

    <node id="0"> 
     <data key="label">A</data> 
     <data key="tag1">0</data> 
     <data key="tag2">0</data> 
    </node> 

    <edge id="0" source="0" target="1"> 
     <data key="label">REFERENCED_TO</data> 
    </edge> 

    </graph> 
</graphml> 

所需的輸出:

<?xml version="1.0" encoding="utf-8"?> 
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"> 
    <graph> 

    <node id="0" label="A">   
     <data key="tag1">0</data> 
     <data key="tag2">0</data> 
    </node> 

    <edge id="0" source="1" target="0" label="REFERENCED_TO"/> 

    </graph> 
</graphml> 

我怎樣才能拉平只有那些data標籤有key屬性設置到"label"

回答

3

我怎樣才能拉平只有擁有這些數據標記關鍵屬性設置爲 「標籤」?

如何:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:gml="http://graphml.graphdrawing.org/xmlns"> 

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

<!-- add label attribute --> 
<xsl:template match="gml:node | gml:edge"> 
    <xsl:copy> 
     <xsl:if test="gml:data[@key='label']"> 
      <xsl:attribute name="label"><xsl:value-of select="gml:data[@key='label']"/></xsl:attribute> 
     </xsl:if> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<!-- suppress label element --> 
<xsl:template match="gml:data[@key='label']"/> 

</xsl:stylesheet> 
+0

相當驚人,我寫的一模一樣的答案(只有輕微的差別),但你已經添加你的。剛剛刪除了我的 - 沒有兩個相同的點。 –

+0

我認爲這可以大大簡化;看到我的答案。 –

1

有一些空閒時間,我想出了下面的XSLT(它是1.0基於這麼漂亮詳細)

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
       xmlns:g="http://graphml.graphdrawing.org/xmlns" 
       exclude-result-prefixes="msxsl" 
> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/"> 
     <xsl:apply-templates /> 
    </xsl:template> 

    <xsl:template match="*[*/@key='label']"> 
     <xsl:element name="{local-name()}" namespace="{namespace-uri()}"> 
     <xsl:copy-of select="@*"/> 
     <xsl:attribute name="label"> 
     <xsl:value-of select="*[@key='label']/text()" /> 
     </xsl:attribute> 
     <xsl:apply-templates select="*[not(@key='label')]"/> 
     </xsl:element> 
    </xsl:template> 

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

</xsl:stylesheet> 

希望這有助於

1

從hor257k的解決方案似乎包含@鍵= '標籤',其中一個會做三個測試。下面就來改善它的嘗試:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:gml="http://graphml.graphdrawing.org/xmlns"> 

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

<!-- convert label element to attribute --> 
<xsl:template match="gml:data[@key='label']"> 
    <xsl:attribute name="label"> 
    <xsl:value-of select="."/> 
    </xsl:attribute> 
</xsl:template> 

</xsl:stylesheet> 

和完整性,這裏的XSLT 3.0版本:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:gml="http://graphml.graphdrawing.org/xmlns"> 

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:mode on-no-match="shallow-copy"/> 

<!-- convert label element to attribute --> 
<xsl:template match="gml:data[@key='label']"> 
    <xsl:attribute name="label" select="."/> 
</xsl:template> 

</xsl:stylesheet> 
+0

恐怕你改進的XSLT 1.0版本只能工作**如果'始終是其父項的第一個**子項。否則,你會得到一個錯誤,如「在包含元素的子元素之後不能創建屬性節點(標籤)」。我不想做出這樣的假設 - 如果有的話,我會說得很清楚。 –

+0

公平評論。 。 。 。 –