使用XSLT将XML元素转换为与现有属性相关的XML属性
我有以下XML:使用XSLT将XML元素转换为与现有属性相关的XML属性,xml,xslt,Xml,Xslt,我有以下XML: <?xml version="1.0" encoding="UTF-8" standalone="no"?> <cars filter="yes"> <car> <brand>Volkswagen</brand> <make>Golf</make> <wheels>4</wheels> <extras hifi="yes" ac=
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<cars filter="yes">
<car>
<brand>Volkswagen</brand>
<make>Golf</make>
<wheels>4</wheels>
<extras hifi="yes" ac="no"/>
</car>
</cars>
大众
高尔夫球
4.
我想展平元素
,这样它就只有属性-没有更多的子元素
到目前为止,我已经制作了以下XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="cars">
<cars>
<xsl:apply-templates/>
</cars>
</xsl:template>
<xsl:template match="car">
<car>
<xsl:for-each select="*">
<xsl:attribute name="{name()}">
<xsl:value-of select="text()"/>
</xsl:attribute>
</xsl:for-each>
</car>
</xsl:template>
</xsl:stylesheet>
这导致:
<cars>
<car brand="Volkswagen" make="Golf" wheels="4" extras=""/>
</cars>
问题:
- 汽车上的“过滤器”属性已消失
- 节点“extras”的属性已消失,但应位于节点“car”中
- 我不需要属性“extras”
<cars filter="yes">
<car brand="Volkswagen" make="Golf" wheels="4" hifi="yes" ac="no"/>
</cars>
对于第一个问题,当
过滤器属性丢失时,您可以通过使用标识模板而不是汽车的特定模板来解决此问题
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
最后,对于extras
的属性,为每个属性添加另一个属性以拾取这些属性
<xsl:for-each select="*/@*">
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
请注意,这假设car
的两个不同子元素没有相同的属性名称
<xsl:for-each select="*/@*">
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="car">
<car>
<xsl:for-each select="*[normalize-space()]">
<xsl:attribute name="{name()}">
<xsl:value-of select="text()"/>
</xsl:attribute>
</xsl:for-each>
<xsl:for-each select="*/@*">
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
</car>
</xsl:template>
</xsl:stylesheet>
<xsl:template match="car">
<car>
<xsl:for-each select="*[normalize-space()]|*/@*">
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
</car>
</xsl:template>