XSLT 转换移动命名空间

XSLT transform moving namespace

我有一个 XML 发布到 Web 服务,但我遇到了问题,因为它需要其他 xml 格式。 我需要转换下一个 xml 添加 xmlns:ans="http://www.ans.gov.br/padroes/tiss/schemas 并从 solicitacaoProcedimentoWS 节点中删除命名空间。

一些帮助将不胜感激。 提前致谢, 路易斯

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <SOAP-ENV:Header/>
  <SOAP-ENV:Body>
    <solicitacaoProcedimentoWS xmlns="http://www.ans.gov.br/padroes/tiss/schemas">
      <cabecalho>
        <identificacaoTransacao>
          <tipoTransacao>SOLICITACAO_PROCEDIMENTOS</tipoTransacao>
          <sequencialTransacao>k1</sequencialTransacao>
        </identificacaoTransacao>
      </cabecalho>
      <hash>393d3f1e310f3385ad0398dd9b65dc4a</hash>
    </solicitacaoProcedimentoWS>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我想转换为:

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ans="http://www.ans.gov.br/padroes/tiss/schemas"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <SOAP-ENV:Header/>
      <SOAP-ENV:Body>
        <ans:solicitacaoProcedimentoWS>
          <ans:cabecalho>
            <ans:identificacaoTransacao>
              <ans:tipoTransacao>SOLICITACAO_PROCEDIMENTOS</ans:tipoTransacao>
              <ans:sequencialTransacao>k1</ans:sequencialTransacao>
            </ans:identificacaoTransacao>
          </ans:cabecalho>
          <ans:hash>393d3f1e310f3385ad0398dd9b65dc4a</ans:hash>
        </ans:solicitacaoProcedimentoWS>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

以下 XSLT 2.0 样式表应该满足您的要求:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
                xmlns:ans="http://www.ans.gov.br/padroes/tiss/schemas">

  <!-- identity transformation - keep everything the same except when overridden -->
  <xsl:template match="@*|node()">
    <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
  </xsl:template>

  <!-- add an extra NS declaration to the document element -->
  <xsl:template match="/*">
    <xsl:copy>
      <xsl:namespace name="ans" select="'http://www.ans.gov.br/padroes/tiss/schemas'"/>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>

  <!-- use a prefixed name for any element in the namespace
       http://www.ans.gov.br/padroes/tiss/schemas -->
  <xsl:template match="ans:*">
    <xsl:element name="ans:{local-name()}" namespace="http://www.ans.gov.br/padroes/tiss/schemas">
      <xsl:apply-templates select="@*|node()" />
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

但真正的问题在于您正在与之交谈的服务 - 如您所知,文件的两个版本在所有相同的命名空间中都具有所有相同的元素,因此任何命名空间都应同等对待感知 XML 处理器。如果他们关心以这种方式使用特定前缀,那么他们可能没有使用适当的命名空间感知 XML 解析器,并且谁知道 XML 规范的其他方面他们忽略或滥用。如果他们要求主体元素以 ans: 前缀命名,是否意味着他们也要求信封使用 SOAP-ENV: 前缀?我过去使用过的至少一个 SOAP 工具包使用 soap: 作为这个命名空间,而不是 SOAP-ENV:...


如果您仅限于 XSLT 1.0,那么您不能使用 <xsl:namespace> 创建任意命名空间绑定,而是尝试类似

<xsl:copy-of select="document('')/*/namespace::ans" />

从样式表文档本身复制命名空间声明。