在 xslt 中使用条件复制不带命名空间



我正在使用这个模板在没有命名空间的情况下进行复制:

<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.comhttp://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因为zzzhttp://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,但这会复制范围内的所有命名空间,最终会得到冗余的命名空间声明。

相关内容

  • 没有找到相关文章