XSLT转换移动命名空间

时间:2015-02-11 11:58:29

标签: xml xslt transform

我有一个XML发布到WebService,我遇到了问题,因为它需要其他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>

1 个答案:

答案 0 :(得分:1)

以下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:前缀命名body元素,这是否意味着他们还要求信封使用SOAP-ENV:前缀?我过去使用的至少一个SOAP工具包使用soap:代替SOAP-ENV: ...


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

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

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