1

私は XSL についてあまり詳しくありませんが、XSL を使用してサード パーティの 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 に答える