我有一个简单的xml文件,我想使用XSLT进行转换。
第一个节点是架构(标头),以下节点是实际数据。请注意,数据中有一些缺少的字段。
<ex:file xmlns:ex="http://example.com">
<ex:header>
<ex:title>houseNumber</ex:title>
<ex:title>street</ex:title>
<ex:title>city</ex:title>
<ex:title>state</ex:title>
</ex:header>
<ex:address>
<ex:field>108</ex:field>
<ex:field>Ridgewood Circle</ex:field>
<ex:field>Rochester</ex:field>
<ex:field>NY</ex:field>
</ex:address>
<ex:address>
<ex:field/>
<ex:field>W. Clark</ex:field>
<ex:field>Springfield</ex:field>
<ex:field>IL</ex:field>
</ex:address>
</ex:file>
我们希望以两种方式转换此XML。 首先,我们想要使用&#34;标题&#34;中的信息。并且用这样的方式替换四个ex:field元素,我可以得到一个看起来像这样的XML:
<ex:file xmlns:ex="http://example.com">
<ex:header>
<ex:title>houseNumber</ex:title>
<ex:title>street</ex:title>
<ex:title>city</ex:title>
<ex:title>state</ex:title>
</ex:header>
<ex:address>
<ex:houseNumber>108</ex:houseNumber>
<ex:street>Ridgewood Circle</ex:street>
<ex:city>Rochester</ex:city>
<ex:state>NY</ex:state>
</ex:address>
<ex:address>
<ex:houseNumber/>
<ex:street>W. Clark</ex:street>
<ex:city>Springfield</ex:city>
<ex:state>IL</ex:state>
</ex:address>
</ex:file>
第二个转变是消除那些空元素:
<ex:file xmlns:ex="http://example.com">
<ex:header>
<ex:title>houseNumber</ex:title>
<ex:title>street</ex:title>
<ex:title>city</ex:title>
<ex:title>state</ex:title>
</ex:header>
<ex:address>
<ex:houseNumber>108</ex:houseNumber>
<ex:street>Ridgewood Circle</ex:street>
<ex:city>Rochester</ex:city>
<ex:state>NY</ex:state>
</ex:address>
<ex:address>
<ex:street>W. Clark</ex:street>
<ex:city>Springfield</ex:city>
<ex:state>IL</ex:state>
</ex:address>
</ex:file>
请注意&#34; houseNumber&#34;在第二个&#34;记录&#34;走了。
我已多次浏览过XSLT教程(http://www.w3schools.com/xsl/default.asp),我不确定这是否可以实际完成。
提前感谢所有人。
答案 0 :(得分:0)
以下转换解决了您的第一个问题。它是一个标识转换,带有一个额外的模板,用于指定应对每个ex:field
元素执行的操作。
XSLT样式表
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ex="http://example.com">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ex:address">
<xsl:copy>
<xsl:for-each select="ex:field">
<xsl:variable name="pos" select="position()"/>
<xsl:element name="{concat('ex:',../../ex:header/ex:title[position() = $pos])}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XML输出
<?xml version="1.0" encoding="utf-8"?>
<ex:file xmlns:ex="http://example.com">
<ex:header>
<ex:title>houseNumber</ex:title>
<ex:title>street</ex:title>
<ex:title>city</ex:title>
<ex:title>state</ex:title>
</ex:header>
<ex:address>
<ex:houseNumber>108</ex:houseNumber>
<ex:street>Ridgewood Circle</ex:street>
<ex:city>Rochester</ex:city>
<ex:state>NY</ex:state>
</ex:address>
<ex:address>
<ex:houseNumber/>
<ex:street>W. Clark</ex:street>
<ex:city>Springfield</ex:city>
<ex:state>IL</ex:state>
</ex:address>
</ex:file>
要同时排除空输入元素,最好将上述for-each
重新配置为匹配ex:field
元素的单独模板。然后,添加第二个匹配ex:field
元素的模板,如果它们不包含任何文本。
XSLT样式表
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ex="http://example.com">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ex:field">
<xsl:variable name="pos" select="position()"/>
<xsl:element name="{concat('ex:',../../ex:header/ex:title[position() = $pos])}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="ex:field[not(text())]"/>
</xsl:stylesheet>
最终XML输出
<?xml version="1.0" encoding="utf-8"?>
<ex:file xmlns:ex="http://example.com">
<ex:header>
<ex:title>houseNumber</ex:title>
<ex:title>street</ex:title>
<ex:title>city</ex:title>
<ex:title>state</ex:title>
</ex:header>
<ex:address>
<ex:houseNumber>108</ex:houseNumber>
<ex:street>Ridgewood Circle</ex:street>
<ex:city>Rochester</ex:city>
<ex:state>NY</ex:state>
</ex:address>
<ex:address>
<ex:street>W. Clark</ex:street>
<ex:city>Springfield</ex:city>
<ex:state>IL</ex:state>
</ex:address>
</ex:file>