我正在使用这个模板在没有命名空间的情况下进行复制:
<xsl:template match="*" mode="copy-no-namespaces">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="node()" mode="copy-no-namespaces"/>
</xsl:element>
</xsl:template>
<xsl:template match="comment()| processing-instruction()" mode="copy-no-namespaces">
<xsl:copy/>
</xsl:template>
这行得通。但我希望它复制没有某些命名空间而不是所有命名空间。例如,我想忽略一些命名空间,例如 http://test.com
、http://test2.com
,副本应该只删除这些命名空间,而不是所有命名空间。
例:
<xs:schema xmlns:xxx="http://include.com" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:zzz="http:test.com" >
<zzz:element>
</zzz:element>
<xxx:complexType>
</xxx:complexType>
</xs:schema>
这里应该删除zzz
命名空间,但保留xxx
因为zzz
只与http://test.com
匹配,所以输出将是
<xs:schema xmlns:xxx="http://include.com" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<element>
</element>
<xxx:complexType>
</xxx:complexType>
</xs:schema>
我怎样才能做到这一点?
我认为您可能会混淆将元素移动到不同的(或没有)命名空间和复制命名空间(即命名空间声明)。您应该只需要将zzz:
前缀元素移动到 no-namespace - 并且不关心输出是否包含现在冗余的命名空间声明:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="http:test.com"
exclude-result-prefixes="ns1">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ns1:*">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
附言如果您愿意,可以在不声明任何前缀的情况下执行相同的操作:
<xsl:template match="*[namespace-uri()='http:test.com']">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
使用具有更高优先级的模板将元素保留在给定的命名空间中:
<xsl:template match="*"
mode="copy-no-namespaces">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node() | @*" mode="copy-no-namespaces"/>
</xsl:element>
</xsl:template>
<xsl:template match="xxx:*" xmlns:xxx="http://include.com"
mode="copy-no-namespaces">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:apply-templates select="node() | @*" mode="copy-no-namespaces"/>
</xsl:element>
</xsl:template>
<xsl:template match="node() | @*"
mode="copy-no-namespaces"
priority="-10">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
第一个模板从元素中剥离命名空间,第二个模板保留元素中的命名空间http://include.com
,最后一个模板复制其他所有内容。
第二个模板可以使用xsl:copy
而不是xsl:element
,但这会复制范围内的所有命名空间,最终会得到冗余的命名空间声明。