【问题标题】:How to get XSL to ignore xmlns short name如何让 XSL 忽略 xmlns 短名称
【发布时间】:2013-03-16 11:06:06
【问题描述】:

我对 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 中的短名称,而只使用它自己的短名称吗?

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

【问题讨论】:

    标签: html xml xslt xml-namespaces


    【解决方案1】:

    “短名称”称为命名空间前缀——您不必在转换中更改命名空间前缀——事实上,它可能与可在 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>
    

    学习经验

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

    【讨论】:

    • 感谢您的回复。我试图保持代码简短并删除不直接相关的位;我不小心删除了太多。你说的正是我的理解。问题是,当唯一的区别是前缀时,它肯定不起作用(对不起,我忘记了终端学)。其他一切都完全相同。我使用的软件有可能做错了吗?我正在使用 VB.Net 的 XslTransform (.Net 4.0)。
    • @user2176753,请编辑问题并提供一个完整(但很小)的代码示例,其他人可以复制。如果不这样做,人们将无法帮助您。
    • 我猜问题是 xsl:if test="@xsi:type='r0:CreditTx' 正在做一个纯字符串比较,而我实际上需要一些东西来比较名称空间。是对吗?我对 XSL 的了解还不够,无法弄清楚如何做到这一点。我会感谢任何帮助。
    • @user2176753,是的,这绝对是一个问题,但我没有看到您当前的问题中描述了这样的问题。
    • 我正在格式化的 XML 可以有数百个交易,大约 20 种不同类型(例如 CreditTx),需要根据类型稍微不同地格式化,因此我需要测试类型。如果有时是 r0:CreditTx 有时是 r:CreditTx (理论上前缀可以是任何东西),有没有什么办法可以在进行字符串比较之前将前缀扩展到完整的命名空间?还是 XSL 有一个聪明的方法来做到这一点?
    猜你喜欢
    • 2011-02-06
    • 2012-02-20
    • 1970-01-01
    • 1970-01-01
    • 2014-12-19
    • 1970-01-01
    • 1970-01-01
    • 2011-01-01
    • 2014-11-12
    相关资源
    最近更新 更多