1

我对 XSL 了解不多,但已经设法使用 XSL 格式化来自 3rd 方 Web 服务的 XML,而没有太多麻烦。但是前几天,一个曾经工作的网站停止了工作。我发现他们对 Web 服务返回的 XML 做了微小的更改。这是过去的工作(大大简化):

更新:我现在看到了问题,但我没有解决方案。问题在于 xsl:if test="@xsi:type='r0:CreditTx'"。将 XSL 中的每个“r0”更改为“s0”,但它不起作用。

我已经用一个工作示例替换了我的原始代码:

XML:

<?xml version="1.0" encoding="unicode"?>
<MyResp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:r0="http://www.foo.com/2.1/schema" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <r0:creditVendReceipt receiptNo="1234567890">
        <r0:transactions>
            <r0:tx xsi:type="r0:CreditTx">
                <r0:amt value="100" />
            </r0:tx>
        </r0:transactions>
    </r0:creditVendReceipt>
</MyResp>

XSL:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:r0="http://www.foo.com/2.1/schema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsl:template match="/">
    <html>
      <head>
      </head>
      <body >
            <xsl:for-each select="MyResp/r0:creditVendReceipt/r0:transactions/r0:tx">
              <xsl:if test="@xsi:type='r0:CreditTx'">
                    <xsl:value-of select="r0:amt/@value"/>
              </xsl:if>
            </xsl:for-each>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

所需的 HTML:

<html xmlns:r0="http://www.foo.com/2.1/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <head>
    <META http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
        100
  </body>
</html>

当 Web 服务将 xmlns 的短名称“a”更改为“a0”时出现问题(它现在发送 xmlns:a0="http://mysite.com/webservice/1.0/schema");命名空间和其他一切都是一样的。我必须在 XSL 中将“a”更改为“a0”才能正常工作(即“GetInfoResp/a0:userName”)。问题是服务发送的短名称不时更改。(在真实的应用程序中,有很多名称空间,而且不同请求之间的短名称甚至会发生变化。)

我认为短名称只是为了使 XML 更短且更易于阅读,而实际名称并不重要(在 XML 和 XSL 之间;在 XSL 中显然必须匹配)。

我可以让 XSL 忽略 XML 中的短名称,而只使用它自己的短名称吗?

抱歉,如果之前回答过这个问题;我查看了其他问题,并没有看到这个具体问题。

4

1 回答 1

2

“短名称”称为名称空间前缀——您不必在转换中更改名称空间前缀——事实上,它可能与可在 XML 文档中使用的任何前缀完全不同。

这种转变

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xYz="http://mysite.com/webservice/1.0/schema"
 exclude-result-prefixes="xYz">

 <xsl:template match="/">
    <html>
        <body >
          <xsl:value-of select="GetInfoResp/xYz:userName"/>
        </body>
    </html>
 </xsl:template>    
</xsl:stylesheet>

产生与此转换完全相同的结果:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:a0="http://mysite.com/webservice/1.0/schema"
  exclude-result-prefixes="a0">

 <xsl:template match="/">
    <html>
        <body >
          <xsl:value-of select="GetInfoResp/a0:userName"/>
        </body>
    </html>
 </xsl:template>
</xsl:stylesheet>

这两种转换,当应用于此 XML 文档时(问题中提供的格式严重错误,必须更正):

<GetInfoResp xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:a0="http://mysite.com/webservice/1.0/schema">
 <a0:userName>Joe</a0:userName>
</GetInfoResp>

产生相同的结果

<html>
   <body>Joe</body>
</html>

教训

重要的是名称空间,而不是用于简写它的前缀。

于 2013-03-16T16:23:52.667 回答