我正在使用此模板进行没有命名空间的复制:
<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>
我怎样才能做到这一点?
答案 0 :(得分:2)
我认为你可能会在将元素移动到不同(或没有)命名空间和复制命名空间(即命名空间声明)之间混淆。您应该只需要将zzz:
前缀元素移动到无命名空间 - 并且无需关心输出是否包含现在冗余的命名空间声明:
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>
P.S。如果您愿意,可以在不声明任何前缀的情况下执行相同的操作:
<xsl:template match="*[namespace-uri()='http:test.com']">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
答案 1 :(得分:0)
使用优先级较高的模板将元素保留在给定的命名空间中:
<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
,但这会复制范围内的所有命名空间,并且您最终会使用冗余的命名空间声明。