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" />
从样式表文档本身复制命名空间声明。
我有一个 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" />
从样式表文档本身复制命名空间声明。