我想使用xslt转换输入xml文件,以更改可以出现在xml树的不同位置的特定元素的名称。
我有一个像下面这样的xml,
<catalog>
<cd>
<ost:title>Empire Burlesque</ost:title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>
<ost:name>Columbia<ost:name>
</company>
<price>10.90</price>
<year>1985</year>
</cd>
</catalog>
我想从所有元素中删除所有'ost:'前缀,并保留其他所有内容,因为它使用的是xslt。一个示例代码将不胜感激。
答案 0 :(得分:2)
在您的示例中,您似乎没有其他名称空间而不是您要删除的名称空间。所以,这是一个XSLT样式表的示例,它从元素中删除所有名称空间(而不仅仅是ost:
)。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- identity template: copy everything as is... -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- ... except for elements,
create a similarly named element without a namespace -->
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
它使用identity transformation按原样复制所有内容,但会覆盖元素以创建具有相同本地名称但没有名称空间的元素。
如果您只想删除ost:
命名空间,可以包含该命名空间的命名空间声明,并将后一个模板更改为匹配ost:*
。
答案 1 :(得分:0)
这种转变是最普遍的。它从全局参数中指定的命名空间中删除所有元素和属性。它还会删除作为其中一个命名空间的所有命名空间节点:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" >
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:delNs>
<ns>some:namespace1</ns>
<ns>some:namespace3</ns>
</my:delNs>
<xsl:variable name="vdelNS"
select="document('')/*/my:delNs/*"/>
<xsl:template match="*">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="namespace::*[not(.=$vdelNS)]"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template priority="10" match=
"*[namespace-uri()=document('')/*/my:delNs/*]">
<xsl:element name="{local-name()}">
<xsl:copy-of select="namespace::*[not(.=$vdelNS)]"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<xsl:template match=
"@*[namespace-uri()=document('')/*/my:delNs/*]">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
将此转换应用于以下XML文档(基于提供的,但已更正为格式良好并扩展为包含3个名称空间及其中的元素和属性):
<catalog xmlns:ost="some:namespace1"
xmlns:x="some:namespace2"
xmlns:y="some:namespace3">
<cd>
<ost:title>Empire Burlesque</ost:title>
<y:artist>Bob Dylan</y:artist>
<country>USA</country>
<company ost:type="big">
<ost:name>Columbia</ost:name>
</company>
<x:price>10.90</x:price>
<year>1985</year>
</cd>
</catalog>
生成了想要的结果:
<catalog xmlns:x="some:namespace2">
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company type="big">
<name>Columbia</name>
</company>
<x:price>10.90</x:price>
<year>1985</year>
</cd>
</catalog>
<强>解释强>:
前两个模板几乎等同于身份规则,但它们不会复制 <my:delNs>
中指定的命名空间的命名空间节点。
最后两个模板适用于属于 <my:delNs>
下列出的命名空间的所有元素和属性。仅在这两个模板中,名称实际上仅更改为本地名称。