你有xml这样的东西:
<q:foo
xmlns:q="http://www.example.com/foo-1_0" xmlns:p="http://www.example.com/common/goo-1_0"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.com/foo/foo-1_0.xsd">
<p:payload>
<p:var-list>
<p:var>
<p:key>key1</p:key>
<p:value xsi:type="xs:string">string content</p:value>
</p:var>
</p:var-list>
</p:payload>
</q:foo>
但是,编写它的人不知道文档命名空间的真实标识符不是http://www.example.com/foo- 1_0 ,而是http://www.example.com/foo- 1_1 即可。所以你需要一个样式表来更新网址。这就是xslt。
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:old="http://www.example.com/foo-1_0"
xmlns:q="http://www.example.com/foo-1_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oldc="http://www.example.com/common/goo-1_0" xmlns:p="http://www.example.com/common/goo-1_1">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:namespace name="xs" select="'http://www.w3.org/2001/XMLSchema'" />
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="@xsi:schemaLocation">
<xsl:attribute name="xsi:{'schemaLocation'}">
<xsl:value-of select="'http://www.example.com/foo/foo-1_1.xsd'"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="old:*">
<xsl:element name="q:{local-name()}">
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
<xsl:template match="oldc:*">
<xsl:element name="p:{local-name()}">
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
并且输出符合预期。
<q:foo xmlns:q="http://www.example.com/foo-1_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/foo/foo-1_1.xsd">
<p:payload xmlns:p="http://www.example.com/common/goo-1_1">
<p:var-list>
<p:var>
<p:key>key1</p:key>
<p:value xsi:type="xs:string">string content</p:value>
</p:var>
</p:var-list>
</p:payload>
</q:foo>
当我尝试验证输出xml时, xsi:type =“xs:string”由于未在输出xml中生成而未得到解析。请问任何人如何将以下内容包含在输出xml的 foo 元素中?
xmlns:xs="http://www.w3.org/2001/XMLSchema"
答案 0 :(得分:1)
当您使用XSLT 2.0并且已经了解<xsl:namespace name="xs" select="'http://www.w3.org/2001/XMLSchema'" />
时,您可以简单地将其放在将old:*
映射到新元素的模板中,因为根元素是其中之一拥有名称空间声明:
<xsl:template match="old:*">
<xsl:element name="q:{local-name()}">
<xsl:namespace name="xs" select="'http://www.w3.org/2001/XMLSchema'" />
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
答案 1 :(得分:0)
您可以使用xsl:copy-of
复制元素上的范围内命名空间:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:old="http://www.example.com/foo-1_0"
xmlns:q="http://www.example.com/foo-1_1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oldc="http://www.example.com/common/goo-1_0"
xmlns:p="http://www.example.com/common/goo-1_1">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template name="CopyNamespaces">
<xsl:copy-of select="namespace::*[. != 'http://www.example.com/foo-1_0' and
. != 'http://www.example.com/common/goo-1_0']"/>
</xsl:template>
<xsl:template match="@xsi:schemaLocation">
<xsl:attribute name="{name()}">
<xsl:text>http://www.example.com/foo/foo-1_1.xsd</xsl:text>
</xsl:attribute>
</xsl:template>
<xsl:template match="old:*">
<xsl:element name="q:{local-name()}">
<xsl:call-template name="CopyNamespaces" />
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
<xsl:template match="oldc:*">
<xsl:element name="p:{local-name()}">
<xsl:call-template name="CopyNamespaces" />
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这是CopyNamespaces
模板的一个额外花哨版本,它也复制了XSLT本身的命名空间,因此您可以在结果文档根元素上使用p
命名空间声明在它之下:
<xsl:template name="CopyNamespaces">
<xsl:copy-of select="(. | document('')/*)/namespace::*
[. != 'http://www.example.com/foo-1_0' and
. != 'http://www.example.com/common/goo-1_0' and
. != 'http://www.w3.org/1999/XSL/Transform']"/>
</xsl:template>