2

明確にするために、XSLTを使用してやりたいことを達成する方法をすでに見つけましたが、それは非常に非効率的であり、将来のスタイルシートの作成に役立つため、別のソリューションを使用できるかどうかを確認したいと思います。

また、次の段落の冗長性について心からお詫び申し上げます。

最低限、ロシア語で書かれ、XMLでエンコードされたストーリー(「pavlova.xml」-残念ながら、ファイルが大きすぎて質問を投稿できませんが、完全に必要というわけではありません)から抽出しようとしています。 SVGで円グラフを生成します。このデータを$chartDataという変数に格納しようとしています。特定の円グラフは全体としてターゲットキャラクター(パラメーター)に関係し、パイの各チャンクはスピーカー(別のキャラクター)を表します。サイズは、各スピーカーが他のスピーカーと比較してターゲットキャラクターについてどれだけ話したかを示します。まず、すべての話者(対象のキャラクターに言及したことのあるキャラクター)を繰り返し処理し、次に特定の話者のスピーチにキャラクターの名前が表示された回数を決定しました。でも、これらの値は、キャラクターが話された回数の合計に関連してのみ役立ちます。円グラフを生成するためのパーセンテージを計算するには、合計が必要です。これを別の変数で個別に計算できることは知っていますが、ノードのシーケンスを変数に格納できるかどうかを確認したいと思います。合計を個別に計算することは、個々のカウントを見つけるパスとほぼ同じパスを通過するため、無駄に思えます。個々の値を取得した後で合計する方がはるかに効率的です。これまでのところ、必要なものはすべて計算できましたが、代わりにxsl:for-eachを使用して変数を反復処理し、変数をシーケンスとして認識させようとしています。円グラフを生成するためのパーセンテージを計算するには、合計が必要です。これを別の変数で個別に計算できることは知っていますが、ノードのシーケンスを変数に格納できるかどうかを確認したいと思います。合計を個別に計算することは、個々のカウントを見つけるパスとほぼ同じパスを通過するため、無駄に思えます。個々の値を取得した後で合計する方がはるかに効率的です。これまでのところ、必要なものはすべて計算できましたが、代わりにxsl:for-eachを使用して変数を反復処理し、変数をシーケンスとして認識させようとしています。円グラフを生成するためのパーセンテージを計算するには、合計が必要です。これを別の変数で個別に計算できることは知っていますが、ノードのシーケンスを変数に格納できるかどうかを確認したいと思います。合計を個別に計算することは、個々のカウントを見つけるパスとほぼ同じパスを通過するため、無駄に思えます。個々の値を取得した後で合計する方がはるかに効率的です。これまでのところ、必要なものはすべて計算できましたが、代わりにxsl:for-eachを使用して変数を反復処理し、変数をシーケンスとして認識させようとしています。合計を個別に計算することは、個々のカウントを見つけるパスとほぼ同じパスを通過するため、無駄に思えます。個々の値を取得した後で合計する方がはるかに効率的です。これまでのところ、必要なものはすべて計算できましたが、代わりにxsl:for-eachを使用して変数を反復処理し、変数をシーケンスとして認識させようとしています。合計を個別に計算することは、個々のカウントを見つけるパスとほぼ同じパスを通過するため、無駄に思えます。個々の値を取得した後で合計する方がはるかに効率的です。これまでのところ、必要なものはすべて計算できましたが、代わりにxsl:for-eachを使用して変数を反復処理し、変数をシーケンスとして認識させようとしています。

変数の形式を次のようにします。

<count name="$speaker1>
    <xsl:value-of select="$spokenCount1"/>
</count>
<count name="$speaker2>
    <xsl:value-of select="$spokenCount2"/>
</count>
...

私はこの問題を解決するために多くの方法を試しましたが、解決できるかどうかはわかりません。最初は、@ as属性を使用してxsl:variableのコンテンツをより正確に定義することでした(具体的には、そのコンテンツをシーケンスとして定義しようとしました)が、その属性とSequenceTypeの動作に関するドキュメントを見つけて理解するのは難しいと感じています。次に、コンテンツを変数に入れる方法を試してみました(変数を宣言してxsl:copy-を使用するのではなく、変数内にfor-eachを直接入れてxsl:value-ofまたはxsl:copy-ofを使用します変数にデータを追加するための外部for-eachのof)。

xsl:sequence(皮肉なことに)とは対照的に、xsl:copy-ofは、ノードのシーケンスを追加するために必要なもののようです。上記のフォーマットは、次のコードでしか取得できませんでした。

<xsl:variable name="chartData"/>
    <xsl:for-each
        select="distinct-values(//speech[.//name[not(parent::nonspeech) and ./@ref eq $character]]/@speaker)">
        <xsl:copy-of select="$chartData"/>
        <xsl:variable name="speaker" select="current()"/>
        <xsl:variable name="spokenCount"
            select="document('pavlova.xml')/count(//speech[@speaker eq $speaker]//name[not(parent::nonspeech) and ./@ref eq $character])"/>
        <count name="{$speaker}">
            <xsl:value-of select="$spokenCount"/>
        </count>
    </xsl:for-each>
    <xsl:variable name="spokenTotal" select="sum($chartData)"/>
    <xsl:value-of select="$chartData"/>
    <!--xsl:for-each select="$chartData/count">
        ...
    </xsl:for-each-->

最終的な目標は、コメントアウトされたfor-下部の各ループが、エラーを発生させるのではなく、各カウント要素を反復処理することです。私の質問は、変数をXMLとして扱い、次のように見える場合は各カウント要素を反復処理できますか、それとも常に文字列として扱われますか?

<?xml version="1.0" encoding="UTF-8"?>
<count name="young-man">4</count>
<count name="olga">24</count>
<count name="cecilija">34</count>
<count name="blonde">1</count>
<count name="vera">32</count>
<count name="servant-fem">6</count>
<count name="valickaja">20</count>
<count name="muse">66</count>
<count name="viktor">4</count>
<count name="dmitrij">15</count>
<count name="anna">11</count>
<count name="iličev">3</count>
<count name="narod">1</count>
<count name="society-man">3</count>

もしそうなら、どのように?

また、誰かが説明できたとしても、変数のスコープ外にfor-eachがあり、selectを「$ chartData」に設定している場合に、xsl:copy-ofのみのdeep-copyを実行するのはなぜですか?変数内でxsl:copy-ofを使用しようとすると、リテラル<count>要素のテキストコンテンツのみがコピーされ、文字列が作成されます:4243413262064641511313)。

4

1 に答える 1

2

あなたの質問は非常に紛らわしいと思います。あなたがやろうとしていることは難しいことではありませんが、あなたが前進するのを助けるためにどこから始めればよいのかを知るのは難しいです。

ノードのシーケンスを変数に格納できるかどうかを確認することに興味があります

はい、できます。新しいノードを作成するのか、それとも変数に既存のノードへの参照を保持させるのかを明確にする必要があります。最初のケースでは、「一時的なツリー」構造を使用します。

<xsl:variable name="tree">
  ... content ...
</xsl:variable>

2番目のケースでは、select属性、または含まれているシーケンスコンストラクターと「as」属性のいずれかを使用できます。

<xsl:variable name="seq" select="expression"/>

また

<xsl:variable name="seq" as="node()*">
  ... content ...
</xsl:variable>

代わりに、xsl:for-eachを使用して変数を反復処理し、変数をシーケンスとして認識させようとしています。

さて、すべての変数の値はシーケンスです、問題は、シーケンスには何が含まれているのかということです。上記の最初の形式の変数(content、no as attribute)を使用する場合、シーケンスは単一のドキュメントノードを含むシングルトンシーケンスになります。たとえば、パス式を使用してその子に移動することをお勧めします<xsl:for-each select="$tree/*"/>。2番目と3番目のケースでは、シーケンスには通常、複数のノードが含まれます。これらのノードは任意の種類のノードである可能性があるため、を書き込む可能性が高くなります<xsl:for-each select="$seq"/>

その属性とSequenceTypeの動作に関するドキュメントを見つけて理解するのが難しいと感じています

どこを見ましたか?私の本「XSLT2.0プログラマーズリファレンス」はあまりお勧めできません...例から試行錯誤するのではなく、実際にどのように機能するのかを理解したいという方だと思います。その本はそのような人のために書かれました。

xsl:sequence(皮肉なことに)とは対照的に、xsl:copy-ofは、ノードのシーケンスを追加するために必要なもののようです。

いいえ、あなたはそれを間違っています。既存のノードへの参照を含む変数を作成する場合は、xsl:sequenceが必要です。ノードのコピーを含む一時ツリーを作成している場合、xsl:sequenceとxsl:copy-ofはまったく同じ効果があり、どちらも選択したノードをコピーします。

変数をXMLとして扱い、次のようになっている場合は各カウント要素を反復処理できますか?

はい、できます。ただし、シーケンスの表現から、これらのノードがドキュメントノードの子であるかどうかを判断することはできません。また、それを知ることが重要です。

変数のスコープ外にfor-eachがあり、selectを'$ chartData'に設定している場合、xsl:copy-ofのみがdeep-copyになるのはなぜですか?変数内でxsl:copy-ofを使用しようとすると、リテラル要素のテキストコンテンツのみがコピーされ、文字列が作成されます。

ここで間違った推論をしました。xsl:copy-ofは常にディープコピーを実行します。ノードの文字列コンテンツのみが表示されている場合は、ノードをアトマイズするか、文字列値を抽出する後続の操作が使用されているためです。

于 2012-07-18T08:19:00.183 に答える