2014-04-06 21 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

公平评论。 。 。 。 –