2011-01-31 11 views
1

私は製品の情報を含む次のxmlを持っています。特定の文字数の後、説明が分割されているため、各製品の説明が次の製品の次の行に表示されることがあります。次の兄弟でxslの再帰呼び出しの問題

<?xml version="1.0" encoding="utf-8"?> 
<root> 
<row> 
    <rowWords>5.00</rowWords> 
    <rowWords>PRODUCTCODE1</rowWords> 
    <rowWords>DESCRIPTIONWORD1</rowWords> 
    <rowWords>DESCRIPTIONWORD2</rowWords> 
    <rowWords>DESCRIPTIONWORD3</rowWords> 
    <rowWords>DESCRIPTIONWORD4</rowWords> 
    <rowWords>DESCRIPTIONWORD5</rowWords> 
    <rowWords>11.28</rowWords> 
    <rowWords>56.40</rowWords> 
</row> 
<row> 
    <rowWords>DESCRIPTIONWORD6</rowWords> 
</row> 
<row> 
    <rowWords>6.00</rowWords> 
    <rowWords>PRODUCTCODE2</rowWords> 
    <rowWords>DESCRIPTIONWORD1</rowWords> 
    <rowWords>DESCRIPTIONWORD2</rowWords> 
    <rowWords>DESCRIPTIONWORD3</rowWords> 
    <rowWords>DESCRIPTIONWORD4</rowWords> 
    <rowWords>DESCRIPTIONWORD5</rowWords> 
    <rowWords>11.00</rowWords> 
    <rowWords>66.00</rowWords> 
</row> 
<row> 
    <rowWords>DESCRIPTIONWORD6</rowWords> 
    <rowWords>DESCRIPTIONWORD7</rowWords> 
    <rowWords>DESCRIPTIONWORD8</rowWords> 
</row> 
<row> 
    <rowWords>DESCRIPTIONWORD9</rowWords> 
    <rowWords>DESCRIPTIONWORD10</rowWords> 
</row> 
<row> 
    <rowWords>10.00</rowWords> 
    <rowWords>PRODUCTCODE3</rowWords> 
    <rowWords>DESCRIPTIONWORD1</rowWords> 
    <rowWords>DESCRIPTIONWORD2</rowWords> 
    <rowWords>10.00</rowWords> 
    <rowWords>100.00</rowWords> 
</row> 
    . 
    . any amount of rows containing products 
    . 
</root> 

の説明だけでなく、製品の変更の数が、私は、単一の行にまとめた製品の説明を持参する方法がわかりません。

これは私がすでに行ったxslです。

<?xml version='1.0'?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="something"> 
<xsl:output indent="yes"/> 
<xsl:template match="/root"> 
<a:Invoice> 
    <Products> 
    <xsl:for-each select="row[position()&gt;=5 and position()&lt;=last()-5]"> 
    <!-- With this if, i prevent create a product node with partial description--> 
    <xsl:if test="number(rowWords[1])"> 
    <Product> 
     <xsl:attribute name="quantity"><xsl:value-of select="rowWords[1]"/></xsl:attribute> 
     <xsl:attribute name="productCode"><xsl:value-of select="rowWords[2]"/></xsl:attribute> 
     <!--Here is the problem (Thank you Dimitri) --> 
     <xsl:attribute name="description"> 
     <xsl:call-template name="constructDescription"> 
      <xsl:with-param name="pRow" select="."/> 
       <xsl:with-param name="pPosition" select="position()"/> 
      </xsl:call-template> 
     </xsl:attribute> 
     <xsl:attribute name="unitValue"><xsl:value-of select="rowWords[last()-1]"/></xsl:attribute> 
     <xsl:attribute name="amount"><xsl:value-of select="rowWords[last()]"/></xsl:attribute> 
    </Product> 
    </xsl:if> 
    </xsl:for-each> 
    </Products> 
</a:Invoice> 
</xsl:template> 


<xsl:template name="constructDescription"> 
    <xsl:param name="pRow"/> 
    <xsl:param name="pPosition"/> 
    <xsl:for-each select="$pRow/*[position() >= 3 and position() &lt;= last() -2]"> 
     <xsl:value-of select="concat(.,' ')"/> 
    </xsl:for-each> 
    <xsl:if test="$pRow/following-sibling::*[not(number(*[1])=number(*[1]))]"> 
     <xsl:call-template name="constructDescription"> 
      <xsl:with-param name="pRow" select="$pRow/following-sibling:: 
       *[position()=number($pPosition)+1]"/> 
     </xsl:call-template> 
    </xsl:if> 
</xsl:template> 
</xsl:stylesheet> 

これは何が起こっている出力

<?xml version='1.0' ?> 
<a:Invoice> 
    <Products> 
    <Product quantity="5.00" productCode="PRODUCTCODE1" description="DESCRIPTIONWORD1 DESCRIPTIONWORD2 DESCRIPTIONWORD3 DESCRIPTIONWORD4 DESCRIPTIONWORD5 DESCRIPTIONWORD6 DESCRIPTIONWORD7 DESCRIPTIONWORD8 DESCRIPTIONWORD9 DESCRIPTIONWORD1 DESCRIPTIONWORD2 DESCRIPTIONWORD3 DESCRIPTIONWORD4 DESCRIPTIONWORD5 DESCRIPTIONWORD6 DESCRIPTIONWORD7 DESCRIPTIONWORD8 DESCRIPTIONWORD9 " unitValue="11.28" amount="56.40"/> 
    <Product quantity="6.00" productCode="PRODUCTCODE2" description="DESCRIPTIONWORD1 DESCRIPTIONWORD2 DESCRIPTIONWORD3 DESCRIPTIONWORD4 DESCRIPTIONWORD5 DESCRIPTIONWORD6 DESCRIPTIONWORD7 DESCRIPTIONWORD8 DESCRIPTIONWORD9 " unitValue="11.00" amount="66.00"/> 
    <Product quantity="10.00" productCode="PRODUCTCODE3" description="DESCRIPTIONWORD1 DESCRIPTIONWORD2 " unitValue="10.00" amount="100.00"/> 
    </Products> 
</a:Invoice> 

のですか?問題は私が再度constructDescriptionを呼び出すときです!しかし、私はそれを修正する方法を知らない!

ありがとうございます!

+0

多くのXMLを読むようにお願いしています。問題のすべてを描写する必要がありますか? –

+0

ありがとう、ジョン!私は私が求めていた方法を変えました!より明確になると思います。 – jechaviz

+0

http://www.ibm.com/developerworks/xml/library/x-xslrecur/ - 役に立つかもしれません。 – Geshan

答えて

2

この変換は、生成物を含むrowあるパラメータと呼ばれる名前付きテンプレートを使用して完全な説明文字列を生成する:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:key name="kFollowingDesc" 
match="row[not(number(*[1])=number(*[1]))]" 
use="generate-id(preceding-sibling::row[number(*[1])=number(*[1])][1])"/> 


<xsl:template match="/"> 
    <xsl:call-template name="constructDescription"> 
    <xsl:with-param name="pRow" select="/*/*[1]"/> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="constructDescription"> 
    <xsl:param name="pRow"/> 

    <xsl:for-each select= 
     "$pRow/*[position() >= 3 
      and 
       not(position() > count($pRow/*) -2) 
       ] 
"> 
    <xsl:value-of select="concat(.,' ')"/> 
</xsl:for-each> 
    <xsl:for-each select="key('kFollowingDesc', generate-id($pRow))"> 
     <xsl:value-of select="concat(.,' ')"/> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

この変換が上に適用されます次のXML文書(あなたが、よく形成され、大幅に切り捨て):

<root> 
    <row> 
     <rowWords>6.00</rowWords> 
     <rowWords>PRODUCTCODE2</rowWords> 
     <rowWords>DESCRIPTIONWORD1</rowWords> 
     <rowWords>DESCRIPTIONWORD2</rowWords> 
     <rowWords>DESCRIPTIONWORD3</rowWords> 
     <rowWords>DESCRIPTIONWORD4</rowWords> 
     <rowWords>DESCRIPTIONWORD5</rowWords> 
     <rowWords>DESCRIPTIONWORD6</rowWords> 
     <rowWords>DESCRIPTIONWORD7</rowWords> 
     <rowWords>DESCRIPTIONWORD8</rowWords> 
     <rowWords>DESCRIPTIONWORD9</rowWords> 
     <rowWords>11.00</rowWords> 
     <rowWords>66.00</rowWords> 
    </row> 
    <row> 
     <rowWords>DESCRIPTIONWORD10</rowWords> 
     <rowWords>DESCRIPTIONWORD11</rowWords> 
     <rowWords>DESCRIPTIONWORD12</rowWords> 
     <rowWords>DESCRIPTIONWORD13</rowWords> 
    </row> 
</root> 

たかった、正しい説明は製造される:

DESCRIPTIONWORD1 DESCRIPTIONWORD2 DESCRIPTIONWORD3 DESCRIPTIONWORD4 DESCRIPTIONWORD5 DESCRIPTIONWORD6 DESCRIPTIONWORD7 DESCRIPTIONWORD8 DESCRIPTIONWORD9 DESCRIPTIONWORD10 DESCRIPTIONWORD11 DESCRIPTIONWORD12 DESCRIPTIONWORD13 

説明

number($x) = number($x) 

:いくつかの項目がある数である場合、この命名テンプレートは、テスト以外は、自明であるべきです$xが数値(または正常に数値にキャストできる任意のタイプの値)の場合、これは正確にtrue()と評価されます。

我々がテストしている:次の行の最初のrowWords子が数ない場合にのみtrue()に評価

not(number(*[1])=number(*[1])) 

- これは、それがより多くの記述語を含むことを意味します。

最後に:すべてこの、OPのコードに統合:この変換は、彼がを提供する新しいXML文書に適用される場合

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="something"> 
    <xsl:output indent="yes"/> 

    <xsl:key name="kFollowingDesc" 
    match="row[not(number(*[1])=number(*[1]))]" 
    use="generate-id(preceding-sibling::row[number(*[1])=number(*[1])][1])"/> 

    <xsl:template match="/root"> 
     <a:Invoice> 
      <Products> 
       <xsl:for-each select="row[number(*[1])=number(*[1])]"> 
        <!-- With this if, i prevent create a product node with partial description--> 
        <xsl:if test="number(rowWords[1])"> 
         <Product> 
          <xsl:attribute name="quantity"> 
           <xsl:value-of select="rowWords[1]"/> 
          </xsl:attribute> 
          <xsl:attribute name="productCode"> 
           <xsl:value-of select="rowWords[2]"/> 
          </xsl:attribute> 
          <!--Here is the problem (Thank you Dimitri) --> 

          <xsl:variable name="vDescriptions"> 
           <xsl:call-template name="constructDescription"> 
            <xsl:with-param name="pRow" select="."/> 
           </xsl:call-template> 
          </xsl:variable> 
          <xsl:attribute name="description"> 
           <xsl:value-of select="normalize-space($vDescriptions)"/> 
          </xsl:attribute> 
          <xsl:attribute name="unitValue"> 
           <xsl:value-of select="rowWords[last()-1]"/> 
          </xsl:attribute> 
          <xsl:attribute name="amount"> 
           <xsl:value-of select="rowWords[last()]"/> 
          </xsl:attribute> 
         </Product> 
        </xsl:if> 
       </xsl:for-each> 
      </Products> 
     </a:Invoice> 
    </xsl:template> 

    <xsl:template name="constructDescription"> 
     <xsl:param name="pRow"/> 

     <xsl:for-each select= 
      "$pRow/*[position() >= 3 
       and 
        not(position() > count($pRow/*) -2) 
        ] 
    "> 
     <xsl:value-of select="concat(.,' ')"/> 
    </xsl:for-each> 
     <xsl:for-each select="key('kFollowingDesc', generate-id($pRow))"> 
      <xsl:value-of select="concat(.,' ')"/> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

<root> 
    <row> 
     <rowWords>5.00</rowWords> 
     <rowWords>PRODUCTCODE1</rowWords> 
     <rowWords>DESCRIPTIONWORD1</rowWords> 
     <rowWords>DESCRIPTIONWORD2</rowWords> 
     <rowWords>DESCRIPTIONWORD3</rowWords> 
     <rowWords>DESCRIPTIONWORD4</rowWords> 
     <rowWords>DESCRIPTIONWORD5</rowWords> 
     <rowWords>11.28</rowWords> 
     <rowWords>56.40</rowWords> 
    </row> 
    <row> 
     <rowWords>DESCRIPTIONWORD6</rowWords> 
    </row> 
    <row> 
     <rowWords>6.00</rowWords> 
     <rowWords>PRODUCTCODE2</rowWords> 
     <rowWords>DESCRIPTIONWORD1</rowWords> 
     <rowWords>DESCRIPTIONWORD2</rowWords> 
     <rowWords>DESCRIPTIONWORD3</rowWords> 
     <rowWords>DESCRIPTIONWORD4</rowWords> 
     <rowWords>DESCRIPTIONWORD5</rowWords> 
     <rowWords>11.00</rowWords> 
     <rowWords>66.00</rowWords> 
    </row> 
    <row> 
     <rowWords>DESCRIPTIONWORD6</rowWords> 
     <rowWords>DESCRIPTIONWORD7</rowWords> 
     <rowWords>DESCRIPTIONWORD8</rowWords> 
    </row> 
    <row> 
     <rowWords>DESCRIPTIONWORD9</rowWords> 
     <rowWords>DESCRIPTIONWORD10</rowWords> 
    </row> 
    <row> 
     <rowWords>10.00</rowWords> 
     <rowWords>PRODUCTCODE3</rowWords> 
     <rowWords>DESCRIPTIONWORD1</rowWords> 
     <rowWords>DESCRIPTIONWORD2</rowWords> 
     <rowWords>10.00</rowWords> 
     <rowWords>100.00</rowWords> 
    </row> . . any amount of rows containing products . 
</root> 

指名手配、正しい結果が得られる

<a:Invoice xmlns:a="something"> 
<Products> 
<Product quantity="5.00" productCode="PRODUCTCODE1" description="DESCRIPTIONWORD1 DESCRIPTIONWORD2 DESCRIPTIONWORD3 DESCRIPTIONWORD4 DESCRIPTIONWORD5 DESCRIPTIONWORD6" unitValue="11.28" amount="56.40" /> 
<Product quantity="6.00" productCode="PRODUCTCODE2" description="DESCRIPTIONWORD1 DESCRIPTIONWORD2 DESCRIPTIONWORD3 DESCRIPTIONWORD4 DESCRIPTIONWORD5 DESCRIPTIONWORD6 DESCRIPTIONWORD7 DESCRIPTIONWORD8 DESCRIPTIONWORD9 DESCRIPTIONWORD10" unitValue="11.00" amount="66.00" /> 
<Product quantity="10.00" productCode="PRODUCTCODE3" description="DESCRIPTIONWORD1 DESCRIPTIONWORD2" unitValue="10.00" amount="100.00" /> 
</Products> 
</a:Invoice> 
+0

こんにちはDimitri。ご回答有難うございます!私はそれを見直して、私は自分のコードをあなたのものとマージする方法を理解していない、笑!もう一度私を助けたいなら、私は感謝します!どうもありがとう!良い答えは – jechaviz

+0

+1です。 – Flack

+0

私もあなたのコードを統合しました、あなたはそれを見ますか?しかし、私はまだ目標を得ることはできません! – jechaviz

関連する問題