首页 > 解决方案 > 通过 xslt 从 xml 中删除不良属性

问题描述

我有一些 xml,我正在尝试删除其他一些 xslt 添加它们的不良属性。

<?xml version="1.0" encoding="UTF-8"?><MYXML xmlns="http://someURL/MYXML" xmlns:role="http://someURL/role">
    <firstElement>
        <LANGUAGE>Spanish</LANGUAGE>
        <VOCABULARY>Spain</VOCABULARY>
    </firstElement>
    <External xmlns="" xmlns:myxml="http://someURL/MYXML">
        <EXTARData/>
        <AnotherElementData>
            <AnotherElement xmlns="http://someURL/AnotherElement"/>
        </AnotherElementData>
    </External>
</MYXML><!--checksum=A477829F524D170104E87187AD2869F5443DD079196B0EDCD5C6B9CFDD315232 version=1-->

我想摆脱 "xmlns="" xmlns:myxml="http://someURL/MYXML"" 没有成功。

我的预期结果是:

<?xml version="1.0" encoding="UTF-8"?><MYXML xmlns="http://someURL/MYXML" xmlns:role="http://someURL/role">
    <firstElement>
        <LANGUAGE>Spanish</LANGUAGE>
        <VOCABULARY>Spain</VOCABULARY>
    </firstElement>
    <External >
        <EXTARData/>
        <AnotherElementData>
            <AnotherElement xmlns="http://someURL/AnotherElement"/>
        </AnotherElementData>
    </External>
</MYXML><!--checksum=A477829F524D170104E87187AD2869F5443DD079196B0EDCD5C6B9CFDD315232 version=1-->

有人可以帮我吗?

标签: xmlxslt

解决方案


因此,您似乎想将 no 命名空间中的元素转换为根元素的命名空间:

  <xsl:template match="*[namespace-uri() = '']">
      <xsl:element name="{local-name()}" namespace="{namespace-uri(/*)}">
          <xsl:apply-templates select="@* | node()"/>
      </xsl:element>
  </xsl:template>

这与身份转换一起给出了

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*[namespace-uri() = '']">
      <xsl:element name="{local-name()}" namespace="{namespace-uri(/*)}">
          <xsl:apply-templates select="@* | node()"/>
      </xsl:element>
  </xsl:template>

</xsl:stylesheet>

并导致https://xsltfiddle.liberty-development.net/eiZQaFX

<MYXML xmlns="http://someURL/MYXML" xmlns:role="http://someURL/role">
    <firstElement>
        <LANGUAGE>Spanish</LANGUAGE>
        <VOCABULARY>Spain</VOCABULARY>
    </firstElement>
    <External>
        <EXTARData />
        <AnotherElementData>
            <AnotherElement xmlns="http://someURL/AnotherElement" xmlns:myxml="http://someURL/MYXML" />
        </AnotherElementData>
    </External>
</MYXML><!--checksum=A477829F524D170104E87187AD2869F5443DD079196B0EDCD5C6B9CFDD315232 version=1-->

如您所见,这并不完全是您所展示的结果,因为 XSLT 1 中的标识转换复制xmlns:myxml="http://someURL/MYXML"AnotherElement.

通过使用 XSLT 2 或 3 处理器,可以轻松避免该问题

https://xsltfiddle.liberty-development.net/eiZQaFX/1

使用 XSLT 1 处理器,您将需要更多的努力来确保在没有任何名称空间的情况下复制元素:

  <xsl:template match="*[namespace-uri() = '']//*[namespace-uri() != '']">
      <xsl:element name="{name()}" namespace="{namespace-uri()}">
          <xsl:apply-templates select="@* | node()"/>
      </xsl:element>
  </xsl:template>

完整的例子是

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*[namespace-uri() = '']">
      <xsl:element name="{local-name()}" namespace="{namespace-uri(/*)}">
          <xsl:apply-templates select="@* | node()"/>
      </xsl:element>
  </xsl:template>

  <xsl:template match="*[namespace-uri() = '']//*[namespace-uri() != '']">
      <xsl:element name="{name()}" namespace="{namespace-uri()}">
          <xsl:apply-templates select="@* | node()"/>
      </xsl:element>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/eiZQaFX/2


推荐阅读