我正在尝试使用以下样式表将输入XML文档属性转换为元素:
/en/?lang=en
然而,尽管基于每个元素属性正确地创建了新元素,但“leaf”元素(即没有子元素)将其文本与创建的元素混合。 E.g。
输入XML
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:for-each select="@*[name()!='type']">
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
<xsl:apply-templates select="*|text()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
输出XML
<order>
<id>12345</id>
<date>Today</date>
<location country="PT">LX</location>
<location country="ES">Barcelona</location>
<items type="array" stock="true">
<item>
<id type="array">item1</id>
<spec>
<color type="array">brown</color>
<price currency="euro">20</price>
<usage>office</usage>
<usage>home</usage>
</spec>
</item>
</items>
</order>
我想要什么
<order>
<id>12345</id>
<date>Today</date>
<location>
<country>PT</country>LX
</location>
<location>
<country>ES</country>Barcelona
</location>
<items>
<stock>true</stock>
<item>
<id>item1</id>
<spec>
<color>brown</color>
<price>
<currency>euro</currency>20
</price>
<usage>office</usage>
<usage>home</usage>
</spec>
</item>
</items>
</order>
我尝试了什么
...
<location>
<text>LX</text>
<country>PT</country>
</location>
<location>
<text>Barcelona</text>
<country>ES</country>
</location>
...
<price>
<text>20</text>
<currency>euro</currency>
</price>
...
问题 尽管正确创建了新元素标签
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:for-each select="@*[name()!='type']">
<xsl:element name="text">
<xsl:value-of select=".."/>
</xsl:element>
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
<xsl:apply-templates select="*|text()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
它还在“非叶子”元素(即带有子元素的元素)上创建“text”元素,获取提供的示例:
<text>20</text>
我不想要
...
<items>
<text>item1brown20officehome</text>
<stock>true</stock>
<item>
<id>item1</id>
<spec>
<color>brown</color>
<price>
<text>20</text>
<currency>euro</currency>20
</price>
<usage>office</usage>
<usage>home</usage>
</spec>
</item>
</items>
...
有什么想法吗?提前谢谢。
答案 0 :(得分:1)
我不确定这是否会创建您想要的确切输出,因为您只包含了所需输出的一部分,但尝试这样的事情......
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="text()"/>
<xsl:apply-templates select="@*|*|comment()|processing-instruction()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[@*]/text()">
<text><xsl:value-of select="."/></text>
</xsl:template>
<xsl:template match="@*">
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
小提琴:http://xsltfiddle.liberty-development.net/jyH9rLX
如果我只想保留名称为&#34; type&#34;如 属性(不将它们转换为元素,而是将它们保存为元素 最初)。我怎么能实现这样的目标呢?
更新了XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@type|text()"/>
<xsl:apply-templates
select="@*[not(name()='type')]|*|comment()|processing-instruction()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[@*]/text()">
<text><xsl:value-of select="."/></text>
</xsl:template>
<xsl:template match="@type">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="@*">
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>