0

私はここ数週間でxsltとxmlを紹介されたばかりであり、私が達成したいことを達成するためにいくつかのコードを書くために緊急に助けが必要です。私は次のxmlを持っています:

<?xml version="1.0" encoding="UTF-8"?>
<abc1 formName="Form">
    <Level1>
        <Element1>ZZZ</Element1>
        <Element2>
            <SubElement1>Apples</SubElement1>
            <SubElement2>Oranges</SubElement2>
            <SubElement3>Pears</SubElement3>
            <SubElement4>Blueberries</SubElement4>
            <SubElement5>Milkshakes</SubElement5>
        </Element2>
    </Level1>
    <Level1>
        <Element1>XXX</Element1>
        <Element2>
            <SubElement1>Apples</SubElement1>
            <SubElement2>Oranges</SubElement2>
            <SubElement3>Kiwifruit</SubElement3>
            <SubElement4>Blueberries</SubElement4>
            <SubElement5>Soda</SubElement5>
        </Element2>
    </Level1>
</abc1>

および次のhtmlテーブル:

<table>
<tr> 
    <td width="180" > Row 1</td>
    <td width="540" colspan="4"> Cell_A</td>
</tr>
<tr> 
    <td width="180" >Types</td>
    <td width="180" >Type 1</td>
    <td width="180" >Type 2</td>
    <td width="180" >Type 3</td>
</tr>
<tr> 
    <td width="180" >Row 2</td>
    <td width="180" >Cell_B</td>
    <td width="180" >Cell_C</td>
    <td width="180" >Cell_D</td>
</tr>
<tr> 
    <td width="180" > Row 3</td>
    <td width="180" >Cell_E</td>
    <td width="180" >Cell_F</td>
    <td width="180" >Cell_G</td>
</tr>
<tr> 
    <td width="180" >Row 4</td>
    <td width="180" >Cell_H</td>
    <td width="180" >Cell_I</td>
    <td width="180" >Cell_J</td>
</tr>
<tr> 
    <td width="180" > Row 5</td>
    <td width="540" colspan="4"> Cell_K</td>
</tr>
</table>

適用する必要のあるルールによってデータが非常に複雑になるため、xsltを使用してxmlからテーブルにデータを抽出するのに問題があります。以下は、私が問題を抱えているセルに適用する必要のあるルールです。

(1)<Element1>値がxml全体で同じである場合、次のようになります。

='ZZZ'の場合<Element1>、Cell_B = '10'、Cell_C = '20'、およびCell_D = '30'

='XXX'の場合<Element1>、Cell_B = '100'、Cell_C = '90'、およびCell_D = '80'

ただし、<Element1>値がxmlで異なる場合は、次のようになります。

Cell_B = '10、100'、Cell_C = '20、90'、およびCell_D = '30、80'

(2)<SubElement5>値がxml全体で同じである場合、次のようになります。

Cell_J=の値<SubElement5>

ただし、<SubElement5>値がxmlで異なる場合は、次のようになります。

Cell_J=<SubElement5>コンマで区切られた両方の値の値

したがって、この場合、Cell_Jの値は「Milkshakes、Soda」になります。

私は以下を使用してさまざまなことを実験してきました:

<xsl:for-each select="./Level1/Element2">
<xsl:value-of select="./SubElement5"/>
</xsl:for-each>

しかし、変数の値を上書きできないため、それらが同じであるかどうかを確認するために使用できるコードを判別できません。

編集: 私が上で示したセル(セルb、c、d、およびj)だけが私が助けを必要としていることに注意してください。さらに、Element1私が遭遇する可能性のある4つの潜在的な値があります:ZZZ、XXX、AAA、およびBBB。これらのそれぞれに必要な値は次のとおりです。(セルb、c、およびd)

ZZZ:10,20,30
XXX:100,90,80
AAA:40,30,30
BBB:50,30,20

したがって、xml全体に潜在的な値が1つしかない場合、セルは上記の値で表示されます。2つの要素1の値が異なる場合、セルは各セルに上記の値をコンマで区切ってリストする必要があります。

cell_jに関しては、もう少し詳しく説明します。

まず、<SubElement5>xml全体でが同じ値であるかどうかを判断する必要があります。この場合はそうではなく、一方のセクションではミルクセーキであり、もう一方のセクションでは「ソーダ」です。したがって、cell_Jには「Milkshakes、Soda」というテキストが含まれている必要があります。

xmlが次のようになっている場合:

<?xml version="1.0" encoding="UTF-8"?>
    <abc1 formName="Form">
        <Level1>
            <Element1>ZZZ</Element1>
            <Element2>
                <SubElement1>Apples</SubElement1>
                <SubElement2>Oranges</SubElement2>
                <SubElement3>Pears</SubElement3>
                <SubElement4>Blueberries</SubElement4>
                <SubElement5>Milkshakes</SubElement5>
            </Element2>
        </Level1>
        <Level1>
            <Element1>XXX</Element1>
            <Element2>
                <SubElement1>Apples</SubElement1>
                <SubElement2>Oranges</SubElement2>
                <SubElement3>Kiwifruit</SubElement3>
                <SubElement4>Blueberries</SubElement4>
                <SubElement5>Milkshakes</SubElement5>
            </Element2>
        </Level1>
    </abc1>

その場合、cell_jの値は「Milkshakes」になります。

助けてくれる人に事前に感謝します。

この質問への回答:

誰かの将来の参考のために、ウッディが以下で行ったことを要約するには:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/abc1">
           <xsl:variable name="elements" select="//Element1[not(preceding::Element1 = .)]"/>
<table>
<tr> 
    <td width="180" > Row 1</td>
    <td width="540" colspan="4"> Cell_A</td>
</tr>
<tr> 
    <td width="180" >Types</td>
    <td width="180" >Type 1</td>
    <td width="180" >Type 2</td>
    <td width="180" >Type 3</td>
</tr>
<tr> 
    <td width="180" >Row 2</td>
    <td width="180" > <xsl:for-each select="$elements">
            <xsl:if test="position() != 1">,</xsl:if>
            <xsl:choose>
                <xsl:when test=". = 'AAA'">40</xsl:when>
                <xsl:when test=". = 'BBB'">50</xsl:when>
                <xsl:when test=". = 'XXX'">100</xsl:when>
                <xsl:when test=". = 'ZZZ'">10</xsl:when>
            </xsl:choose>
        </xsl:for-each></td>
    <td width="180" ><xsl:for-each select="$elements">
            <xsl:if test="position() != 1">,</xsl:if>
            <xsl:choose>
                <xsl:when test=". = 'AAA'">30</xsl:when>
                <xsl:when test=". = 'BBB'">30</xsl:when>
                <xsl:when test=". = 'XXX'">90</xsl:when>
                <xsl:when test=". = 'ZZZ'">20</xsl:when>
            </xsl:choose>
        </xsl:for-each></td>
    <td width="180" ><xsl:for-each select="$elements">
            <xsl:if test="position() != 1">,</xsl:if>
            <xsl:choose>
                <xsl:when test=". = 'AAA'">30</xsl:when>
                <xsl:when test=". = 'BBB'">20</xsl:when>
                <xsl:when test=". = 'XXX'">80</xsl:when>
                <xsl:when test=". = 'ZZZ'">30</xsl:when>
            </xsl:choose>
        </xsl:for-each></td>
</tr>
<tr> 
    <td width="180" > Row 3</td>
    <td width="180" >Cell_E</td>
    <td width="180" >Cell_F</td>
    <td width="180" >Cell_G</td>
</tr>
<tr> 
    <td width="180" >Row 4</td>
    <td width="180" >Cell_H</td>
    <td width="180" >Cell_I</td>
    <td width="180" ><xsl:for-each select="//SubElement5[not(preceding::SubElement5/text() = text())]">
       <xsl:if test="position() &gt; 1">, </xsl:if>
       <xsl:value-of select="."/>
    </xsl:for-each></td>
</tr>
<tr> 
    <td width="180" > Row 5</td>
    <td width="540" colspan="4"> Cell_K</td>
</tr>
</table>
        </xsl:template>
    </xsl:stylesheet>

ウッディ、ありがとう。これは最高でした。

4

1 に答える 1

2

問題の鍵は、必要な答えが固定されているため、データを繰り返し処理して必要なものを取得できないことです。そのため、一度に各セクションを受講する必要があります。

Level1 は 2 つしかありませんか?

        <xsl:template match="/abc1">
            <table>
                <tr> 
                    <td width="180" >Row 2</td>
            <xsl:choose>
                <xsl:when test="not(Level1/Element1='XXX')">
                    <!-- only ZZZ -->
                        <td width="180" >10</td>
                        <td width="180" >20</td>
                        <td width="180" >30</td>
                </xsl:when>
                <xsl:when test="not(Level1/Element1='ZZZ')">
                    <!-- only YYY -->
                        <td width="180" >100</td>
                        <td width="180" >90</td>
                        <td width="180" >80</td>   
                </xsl:when>
                <xsl:otherwise>
                    <!-- some combination -->
                        <td width="180" >10,100</td>
                        <td width="180" >20,90</td>
                        <td width="180" >30,80</td>
                </xsl:otherwise>
                </xsl:choose>
                </tr>
                .. continued
            </table>
        </xsl:template>
    </xsl:stylesheet>

セクションごとなど。多数の行があり、カンマで区切る場合は、セクションごとに行うか、セクションごとに 1 つのカンマ リストを配置する必要があります。

申し訳ありませんが、cell_j で何をしようとしているのかわかりませんでした。また、他のものにはルールがないようです。

編集:ただし、2 つだけではなく多くの項目があり、カンマ区切りのリストが必要な場合は、xpath を使用して実行できます。

<tr>
  <td>
    <xsl:for-each select="//SubElement5[not(preceding::SubElement5/text() = text())]">
       <xsl:if test="position() &gt; 1">, </xsl:if>
       <xsl:value-of select="."/>
    </xsl:for-each>
  </td>
  .. maybe other rows the same
</tr>

もう一度編集します。

したがって、cell_j に関する更新された質問については、上記で正しい値が得られます。

最初のセクションの更新では、すべての値を表示する必要がある場合は、同じテーマでバリエーションを作成できます (したがって、4 つのオプションがすべてある場合は 4 つの値があります)。残念ながら、それぞれに固定値があり、それぞれを1つずつ実行する必要があるため、大きなセクションで実行する必要があるため、ループで:

<xsl:for-each select="//Element1[not(preceding::Element1/text() = text())]">

これにより、一意のエントリごとにループし、その値が XXX、ZZ​​Z などであるかどうかに基づいて要素を選択します。

再編集

必要な最初のセクションを実行するには、再帰関数、外部ドキュメント、さまざまな XSLT 実装のノード セット関数の使用など、いくつかの方法があります。バージョンを参照してください(願っています):

<xsl:variable name="elements" select="//Element1[not(preceding::Element1 = .)]"/>
<table>
    <tr> 
        <td width="180" >Row 2</td>
    <td>
        <xsl:for-each select="$elements">
            <xsl:if test="position() != 1">,</xsl:if>
            <xsl:choose>
                <xsl:when test=". = 'AAA'">40</xsl:when>
                <xsl:when test=". = 'BBB'">50</xsl:when>
                <xsl:when test=". = 'XXX'">100</xsl:when>
                <xsl:when test=". = 'ZZZ'">10</xsl:when>
            </xsl:choose>
        </xsl:for-each>
    </td>
    <td>
        <xsl:for-each select="$elements">
            <xsl:if test="position() != 1">,</xsl:if>
            <xsl:choose>
                <xsl:when test=". = 'AAA'">30</xsl:when>
                <xsl:when test=". = 'BBB'">30</xsl:when>
                <xsl:when test=". = 'XXX'">90</xsl:when>
                <xsl:when test=". = 'ZZZ'">20</xsl:when>
            </xsl:choose>
        </xsl:for-each>
    </td>
    <td>
        <xsl:for-each select="$elements">
            <xsl:if test="position() != 1">,</xsl:if>
            <xsl:choose>
                <xsl:when test=". = 'AAA'">30</xsl:when>
                <xsl:when test=". = 'BBB'">20</xsl:when>
                <xsl:when test=". = 'XXX'">80</xsl:when>
                <xsl:when test=". = 'ZZZ'">30</xsl:when>
            </xsl:choose>
        </xsl:for-each>
    </td>
    </tr>
 </table>   

実際には、変数 (この場合は $elements) の反復がその標準であるかどうかはわかりません。それは saxon と msxsl のものかもしれませんが、そうでない場合は、値 (//Element1 [not(先行::Element1 = .)])

于 2012-06-07T11:48:22.050 に答える