我想使用XSLT压缩XML文件。示例(可能有任意数量的node
和edge
节点):
输入:
<?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
的{{1}}代码?
答案 0 :(得分: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>
答案 1 :(得分: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>
希望这有帮助,
答案 2 :(得分:1)
来自hor257k的解决方案似乎包含三个@ key ='label'测试,其中一个会做。这是尝试改进它:
<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>