4

ドキュメント内の特定のタイプ (//@arch など) のすべての属性を選択し、そのノード セットを取得して、値を 2 番目のノード セットに解析できるようにしたいと考えています。「解析」と言うとき、具体的には、ノードセットを次のように変更したいという意味です。

arch="value1;value2;value3"
arch="value1:value4"

次のようなノード セットに変換します。

arch="value1"
arch="value2"
arch="value3"
arch="value1"
arch="value4"

またはそのようなもの; 個々の値を属性から独自のノードに取得したいと考えています。

その状態にすることができれば、並べ替えと重複の削除のための方法がたくさんあります。その後、完成したノード セットをパブリッシュ タスクに使用することになります。

ここでは、アプローチとしてきちんとした答えを探しているわけではありません。XSLT が動的配列を実行できないことは知っていますが、それは、動的配列や、機能の重要な部分を模倣する何かを実行できないことと同じではありません。

私が思いついたのは、最初のノード セットのノードと区切り記号の数を数え、2 番目のノード セットに必要なエントリの数を計算して (何らかの方法で) 作成し、部分文字列関数を使用できるということです。最初のノード セットを 2 番目のノード セットに解析します。

通常、XSLT の問題を回避する方法があります。誰かが以前にこれを回避したことがありますか?

助けてくれてありがとう、ジェフ。

4

2 に答える 2

2

tokenize式で関数を使用してfor、個別の値のシーケンスを取得し、それぞれの属性ノードを作成できます。ただし、XSLT では要素の親を持たない裸の属性ノードを作成できないため、次のようなトリックを使用する必要があります。

<xsl:variable name="archElements">
  <xsl:for-each select="for $attr in $initialNodeSet
                        return tokenize($attr, '[:;]')">
    <dummy arch="{.}" />
  </xsl:for-each>
</xsl:variable>

次に、$archElements/dummy/@arch必要な分離されたarch属性ノードのセットである必要があります。

完全な例:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

  <xsl:output indent="yes" />

  <xsl:template match="/">
    <xsl:variable name="inputData">
      <a arch="value1;value2;value3" />
      <a arch="value1:value4" />
    </xsl:variable>

    <!-- create an example node set containing the two arch attribute nodes -->
    <xsl:variable name="initialNodeSet" select="$inputData/a/@arch" />

    <!-- tokenize and generate one arch attribute node for each value -->
    <xsl:variable name="archElements">
      <xsl:for-each select="for $attr in $initialNodeSet
                            return tokenize($attr, '[:;]')">
        <dummy arch="{.}" />
      </xsl:for-each>
    </xsl:variable>

    <!-- output to verify -->
    <r>
      <xsl:for-each select="$archElements/dummy/@arch">
        <c><xsl:copy-of select="."/></c>
      </xsl:for-each>
    </r>
  </xsl:template>
</xsl:stylesheet>

入力ドキュメントを実行する(コンテンツは無視されます)、これが生成されます

<?xml version="1.0" encoding="UTF-8"?>
<r>
   <c arch="value1"/>
   <c arch="value2"/>
   <c arch="value3"/>
   <c arch="value1"/>
   <c arch="value4"/>
</r>
于 2013-08-20T15:56:38.567 に答える
2

あなたが探しているのはシーケンスだと思います。シーケンスは、ノードまたはアトミック値のいずれかになります ( http://www.w3.org/TR/xslt20/#constructing-sequencesを参照)。

これは、シーケンスの構築とそれを反復する例を示しています。シーケンスは のアトミック値ですが@arch、ノードの場合もあります。

XML 入力

<doc>
    <foo arch="value1;value2;value3"/>
    <foo arch="value1:value4"/>
</doc>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="archSequence" as="item()*">
        <xsl:for-each select="//@arch">
            <xsl:for-each select="tokenize(.,'[;:]')">
                <xsl:value-of select="."/>                  
            </xsl:for-each>             
        </xsl:for-each>         
    </xsl:variable>

    <xsl:template match="/*">
        <sequence>
            <xsl:for-each select="$archSequence">
                <item><xsl:value-of select="."/></item>
            </xsl:for-each>
        </sequence>
    </xsl:template>

</xsl:stylesheet>

XML 出力

<sequence>
   <item>value1</item>
   <item>value2</item>
   <item>value3</item>
   <item>value1</item>
   <item>value4</item>
</sequence>

要素のシーケンスの例 (同じ出力):

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="archSequence" as="element()*">
        <xsl:for-each select="//@arch">
            <xsl:for-each select="tokenize(.,'[;:]')">
                <item><xsl:value-of select="."/></item>         
            </xsl:for-each>             
        </xsl:for-each>         
    </xsl:variable>

    <xsl:template match="/*">
        <sequence>
            <xsl:for-each select="$archSequence">
                <xsl:copy-of select="."/>
            </xsl:for-each>
        </sequence>
    </xsl:template>

</xsl:stylesheet>
于 2013-08-20T15:56:53.217 に答える