在XML中,有一些项目具有0-n属性,并且应该为每个属性复制一个项目作为新项目,但只有一个属性。
给出的是这样的XML:
<?xml version="1.0" encoding="utf-8" ?>
<items>
<item>
<name>A</name>
<attributes>
<attribute>
<key>attribute1</key>
<value>1</value>
</attribute>
</attributes>
</item>
<item>
<name>B</name>
</item>
<item>
<name>C</name>
<attributes>
<attribute>
<key>attribute1</key>
<value>5</value>
</attribute>
<attribute>
<key>attribute2</key>
<value>2</value>
</attribute>
<attribute>
<key>attribute3</key>
<value>1</value>
</attribute>
</attributes>
</item>
</items>
结果应该是:
<?xml version="1.0" encoding="utf-8" ?>
<root>
<item>
<name>A</name>
<attribute_key>attribute1</attribute_key>
<attribute_value>1</attribute_value>
</item>
<item>
<name>B</name>
</item>
<item>
<name>C</name>
<attribute_key>attribute1</attribute_key>
<attribute_value>5</attribute_value>
</item>
<item>
<name>C</name>
<attribute_key>attribute2</attribute_key>
<attribute_value>2</attribute_value>
</item>
<item>
<name>C</name>
<attribute_key>attribute3</attribute_key>
<attribute_value>1</attribute_value>
</item>
</root>
我到目前为止:
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="item">
<xsl:if test="not(attributes/attribute)">
<item>
<xsl:apply-templates select="@* | node()"/>
</item>
</xsl:if>
<xsl:for-each select="./attributes/attribute">
<xsl:copy-of select="ancestor::item"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
所以,父母&#34;项目&#34;节点被正确复制但如何删除所有属性,但是从for-each中删除该属性并将该属性作为&#34; item&#34;的直接子节点??
答案 0 :(得分:1)
不是复制item
节点,而是手动创建新的item
并仅复制其子节点(attributes
除外)
<xsl:for-each select="attributes/attribute">
<item>
<xsl:copy-of select="ancestor::item/*[not(self::attributes)]"/>
<!-- Process attributes here -->
</item>
</xsl:for-each>
处理属性只是处理子项的问题,并使用xsl:element
创建新的
<xsl:for-each select="*">
<xsl:element name="attribute_{local-name()}">
<xsl:value-of select="." />
</xsl:element>
</xsl:for-each>
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="item">
<xsl:if test="not(attributes/attribute)">
<item>
<xsl:apply-templates select="@* | node()"/>
</item>
</xsl:if>
<xsl:for-each select="attributes/attribute">
<item>
<xsl:copy-of select="ancestor::item/*[not(self::attributes)]"/>
<xsl:for-each select="*">
<xsl:element name="attribute_{local-name()}">
<xsl:value-of select="." />
</xsl:element>
</xsl:for-each>
</item>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
或者,如果您想采用更基于模板的方法,这也应该有效
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="item[attributes/attribute]">
<xsl:apply-templates select="attributes/attribute" />
</xsl:template>
<xsl:template match="item">
<item>
<xsl:apply-templates select="@* | node()"/>
</item>
</xsl:template>
<xsl:template match="attribute">
<item>
<xsl:copy-of select="ancestor::item/*[not(self::attributes)]"/>
<xsl:apply-templates select="*" />
</item>
</xsl:template>
<xsl:template match="attribute/*">
<xsl:element name="attribute_{local-name()}">
<xsl:value-of select="." />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
看一下下面的脚本,它会解释你想要的是:
<?xml version="1.0" encoding="utf-8" ?>
<xsl:template match="/">
<root>
<xsl:apply-templates select="items/item" />
</root>
</xsl:template>
<xsl:template match="item">
<xsl:if test="not(attributes/attribute)">
<xsl:copy-of select="."></xsl:copy-of>
</xsl:if>
<xsl:apply-templates select="attributes/attribute">
<!-- sending value of name tag to a template matching attribute tag -->
<xsl:with-param name="name" select="name"></xsl:with-param>
</xsl:apply-templates>
</xsl:template>
<!--Another template for attribute tag that will help individually tracking of attribute -->
<xsl:template match="attribute">
<!-- Taking value of name tag -->
<xsl:param name="name"></xsl:param>
<item>
<name>
<xsl:value-of select="$name" />
</name>
<attribute_key>
<xsl:value-of select="key" />
</attribute_key>
<attribute_value>
<xsl:value-of select="value" />
</attribute_value>
</item>
</xsl:template>