首页 文章

如何让XSL忽略xmlns短名称

提问于
浏览
1

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

Update: 我现在看到了问题,但我没有解决方案 . 问题出在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中的短名称,只使用自己的短名称吗?

对不起,如果之前得到了答复;我通过其他问题看了看,没有看到这个具体问题 .

1 回答

  • 2

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

    This transformation

    <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>
    

    produces exactly the same result as this transformation:

    <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>
    

    Both transformations, when applied on this XML document (问题中提供的内容严重错误,必须予以纠正):

    <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>
    

    produce the same result

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

    Lesson to learn

    重要的是命名空间,而不是用于缩写它的前缀 .

相关问题