0

XML現在のファイルと他の2つのファイルのデータに基づいた値を持つ新しい要素を追加してXMLファイルを変換する必要がありますXSLT 1.0。ファイル:

ファイル1:

<Table>
    <Row>
        <ColA>AValue1</ColA>
        <ColB>BValue1</ColB>
    </Row>
    <Row>
        <ColA>AValue2</ColA>
        <ColB>BValue2</ColB>
    </Row>
</Table>

File2:

<Table>
    <Row>
        <ColA>AValue1</ColA>
        <ColB>BValue1</ColB>
        <ColC>CValue1</ColC>
    </Row>
    <Row>
        <ColA>AValue1</ColA>
        <ColB>BValue1</ColB>
        <ColC>CValue1</ColC>
    </Row>
<Row>
        <ColA>AValue1</ColA>
        <ColB>BValue1</ColB>
        <ColC>CValue2</ColC>
    </Row>
    <Row>
        <ColA>AValue1</ColA>
        <ColB>BValue1</ColB>
        <ColC>CValue3</ColC>
    </Row>
    <Row>
        <ColA>AValue2</ColA>
        <ColB>BValue2</ColB>
        <ColC>CValue1</ColC>
    </Row>
</Table>

File3:

<Table>
    <Row>
        <ColC>CValue1</ColC>
        <ColD>ABC</ColD>
    </Row>
    <Row>
        <ColC>CValue2</ColC>
        <ColD>DEF</ColD>
    </Row>
    <Row>
        <ColC>CValue3</ColC>
        <ColD>DEF</ColD>
    </Row>
</Table>

File1の行は、ColAおよびColBによってFile2の行と1対多の関係にあります。

File2の行は、ColCによるFile3の行と多対1の関係にあります。

File1の各行について、次のことを行う必要があります。

  1. ColAとColBで一致する行について、File2で個別のColC値を検索します

  2. 個別のColC値ごとに、File3でColD値を検索して、ColCで一致する行を探します

  3. 手順2で検索されたColD値の出現回数をカウントします。ColDは2つの値(「ABC」または「DEF」など)のいずれかになります。「DEF」よりも「ABC」が多いかどうかを知る必要があります。ある場合は、File1のその行に<ColD> ABC</ColD>を追加します。それ以外の場合は、File1のその行に<ColD> DEF</ColD>を追加します。最後に、File1の各行には<ColD> ABC</ColD>または<ColD>DEF</ColD>が必要です。

望ましい結果(File1が変換されました):

<Table>
    <Row>
        <ColA>AValue1</ColA>
        <ColB>BValue1</ColB>
        <ColD>DEF</ColD>
    </Row>
    <Row>
        <ColA>AValue2</ColA>
        <ColB>BValue2</ColB>
        <ColD>ABC</ColD>
    </Row>
</Table>

<ColD> DEF </ ColD>は、ABCが1回(個別に)発生したのに対し、DEFが2回発生したため、最初の行に追加されます。ABCが1回発生し、DEFがゼロだったため、<ColD> ABC</ColD>が行2に追加されます。

4

2 に答える 2

0

さて、提案してみますが、よくわからないので、意味がわからない場合は削除します。

関連するXmlファイルモデルをいくつか入手したとのことですが。つまり、File1の要素に関連するファイル2の要素に到達する必要があるということです。私はいくつかの同様のケースを取得し、最初の変換を適用してすべてのファイルのすべての参照を最初に解決し(XMLノードをどこにでも複製)、この「無関係なモデル」にさらに詳細な変換を適用することで修正しました。はるかに簡単ですが、パフォーマンスの問題が発生する可能性があります(多くの関係がある場合は、すべてのファイルの関連付けを解除すると長くなる可能性があります)。私の場合はオフライン生成用であるため、優れたパフォーマンスは必要ありません。

于 2012-10-31T17:28:12.813 に答える
0

私はうまくいくように見える解決策を思いついた(それをあまりテストしていない)。ここで再入力しているので、タイプミスに注意してください。私が最も苦労したのは、一意のColC値を選択する方法を見つけることでした。ソリューションをもう一度見ると、一意の値は必要ありませんでした。$ unique_c_valuesをループしてColD値をカウントすることを考えていましたが、結果は異なります。

<xsl:template match="node()|@">
    <xsl:copy>
        <xsl:apply-templates select="node()|@">
    </xsl:copy>
</xsl:template>

<xsl:template match="Row">
    <xsl:copy>
        <xsl:apply-templates select="node()|@">

        <xsl:variable name="unique_c_values" select=
            "document('file2.xml')/Table/Row[current()/ColA = ColA and current()/ColB = ColB]/ColC[not(. = preceding-sibling::*/ColC[current()/ColA = ../ColA and current()/ColB = ../ColB])]"/>

        <xsl:variable name="d_values" select=
            "document('file3.xml')/Table/Row[ColC = $unique_c_values]/ColD"/>

        <xsl:choose>
            <xsl:when test="count($d_values[. = 'DEF']) &gt; count($d_values[. = 'ABC'])">
                <ColD>DEF</ColD>
            </xsl:when>
            <xsl:otherwise>
                <ColD>ABC</ColD>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:copy>
</xsl:template>
于 2012-11-06T21:03:44.690 に答える