1

ID を介して関連付けられた異なるノード間の関係を含む、変換しようとしている XML がありますが、それらを「接着」する方法がわかりません。

XML の例:

<order>
 <products>     
  <product id="1234">
   <item quantity="5" colour="red">
   <item quantity="2" colour="blue">
  </product> 
  <product id="9876">
   <item quantity="10" colour="teal">
  </product>
 </products>

 <prices>
  <productprice>
   <refProduct id="1234" />
   <price gross="9.99" />
  </productprice>
  <productprice>
   <refProduct id="9876" />
   <price gross="6.89" />
  </productprice>
 </prices>
</order>

私の望ましい結果は、for-each を介して製品を表示し、それぞれの価格を横にリストできるようなものです。

手がかりはありがたく受け取った。

編集: レネゲード製品要素を修正しました。例は適切な形式にする必要があります

4

3 に答える 3

1

これは、必要な接続を確立するための簡単な概念実証です。入力 XML は整形式ではなかったので、products 要素が 1 つだけで、複数の product 子があると仮定しました。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/">
        <products>
            <xsl:for-each select="order/products/product">
                <product>
                    <xsl:variable name="productid" select="@id"/>
                    <xsl:attribute name="id">
                        <xsl:value-of select="$productid"/>
                    </xsl:attribute>
                    <xsl:attribute name="price">
                        <xsl:value-of
                            select="/order/prices/productprice[refProduct[@id = $productid]]/price/@gross"/>
                    </xsl:attribute>
                </product>
            </xsl:for-each>
        </products>
    </xsl:template>
</xsl:stylesheet>

次の出力が得られます。

<?xml version="1.0" encoding="utf-8"?>
<products>
    <product id="1234" price="9.99"/>
    <product id="9876" price="6.89"/>
</products>
于 2012-08-21T16:43:25.253 に答える
0

要素の検索に関しては、これはxsl:keyを使用するのに理想的な状況です。したがって、サンプルでは、​​製品の価格を調べたい場合があるため、次のようにキーを定義します

<xsl:key name="prices" match="productprice" use="refProduct/@id" />

したがって、これにより、製品 ID の値を使用して、productprice要素にアクセスできるようになります。具体的には、製品要素に配置されている場合、次のようにキーにアクセスして総額を取得します。

<xsl:value-of select="key('prices', @id)/price/@gross" />

製品の表示に関しては、一般的に言えば、XSLT の「精神」に沿っているため、 xsl:for-eachよりもxsl:apply-templatesを使用する方が望ましいことがよくあります。

<xsl:apply-templates select="products/product" />

テンプレートを複数の場所で呼び出してコードの重複を減らすことができ、特にコードのインデントを減らすことで、コードを読みやすくすることができます。

ここに完全な XSLT があります

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:key name="prices" match="productprice" use="refProduct/@id" />

   <xsl:template match="/order">
      <table>
      <xsl:apply-templates select="products/product" />
      </table>
   </xsl:template>

   <xsl:template match="product">
      <tr>
         <td><xsl:value-of select="@id" /></td>
         <td><xsl:value-of select="key('prices', @id)/price/@gross" /></td>
      </tr>
   </xsl:template>
</xsl:stylesheet>

次の整形式 XML に適用すると、

<order>
   <products>
      <product id="1234">
         <item quantity="5" colour="red"/>
         <item quantity="2" colour="blue"/>
      </product>
      <product id="9876">
         <item quantity="10" colour="teal"/>
      </product>
   </products>
   <prices>
      <productprice>
         <refProduct id="1234"/>
         <price gross="9.99"/>
      </productprice>
      <productprice>
         <refProduct id="9876"/>
         <price gross="6.89"/>
      </productprice>
   </prices>
</order>

以下が出力されます

<table>
  <tr>
    <td>1234</td>
    <td>9.99</td>
  </tr>
  <tr>
    <td>9876</td>
    <td>6.89</td>
  </tr>
</table>
于 2012-08-21T16:54:21.303 に答える
0

あなたの XML は整形式ではないため、質問に正確に答えることが難しくなっています。しかし、おそらくこれに沿った何か?

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <out>
      <xsl:apply-templates/>
    </out>
  </xsl:template>
  <xsl:template match="/root/order/products/product">
    <xsl:variable name="id" select="string(@id)" />
    <prod id="{@id}">
      <xsl:value-of select="/root/prices/productprice[refProduct/@id=$id]/price/@gross" />
    </prod>
  </xsl:template>
</xsl:stylesheet>

明らかに、正確な XPath は XML の構造によって異なりますが、このようなものは製品と価格を一致させます。製品を反復する必要がある場合は、関数に移動できます。

于 2012-08-21T16:52:52.640 に答える