2012-02-06 9 views
0

<leg>は、旅行の脚を記録します。出張は文書順に記録されます。いくつかの足は、同じ場所(例えば、MAからMA)で始まり、終わるものもあれば、場所によっては(例えば、MAからCTへ)移動するものもある。開始位置と終了位置に関する一部のデータがありません。 XSLT/XPATH 1.0を使用してアトリビュート内のデータの順序付けとデデップアップ

<trip> 
    <leg start="MA" stop="MA" /> 
    <leg start="MA" stop="CT" /> 
    <leg start="NY"   /> 
    <leg      /> 
    <leg start="DE"   /> 
    <leg   stop="DE" /> 
    <leg start="NY" stop="PA" /> 
</trip> 

、私は、場所のリストが欲しい訪れたために:

<trip> 
    <place>MA</place> 
    <place>CT</place> 
    <place>NY</place> 
    <place>DE</place> 
    <place>NY</place> 
    <place>PA</place> 
</trip> 

編集:

[OK]を、私は私が行う方法を見ると思いますそれ:

<xsl:template match="leg" mode="tour"> 
    <xsl:if test="string(@start)"> 
     <place><xsl:value-of select="@start"></place> 
    </xsl:if> 
    <xsl:if test="string(@end)"> 
     <place><xsl:value-of select="@end"></place> 
    </xsl:if> 
</xsl:template> 


<xsl:variable name="rtfPlaces"> 
    <xsl:apply-templates select="trip/leg" mode="tour" /> 
</xsl:variable> 

<xsl:variable name="places" select="exslt:node-set($rtfPlaces)" /> 

<xsl:variable name="uniquePlaces" select="$places/place[1] | $places/place[.!=preceding-sibling::place[1]]" /> 

解決策:実際には2回の処理で処理しますか? @startと@endを必要な順序で別々に出力してください。次に、2回目のパスで一意の値を選択します。

出力にtrip要素が表示されませんが、本当に必要とは思われません。

ノードセットの拡張が必要ですが、それでも問題ありません。

すべてが1回のパスで実行できる場合、私はどのように見えません。これは、1回のパスでそれを取得する必要があります

+0

お聞きしたい質問はどのように素敵な...ありますか?これは「私のためにこのコードを書いてください」というサイトではなく、「ここで私が試したことは何ですか?それは間違っていますか? –

+0

私は私の個人的なバングリングを私がしたときよりも受け入れなかったとき、私は一般的にもっとフレンドリーな返事をしました。犯罪に対する私の謝罪。この1つでは、どこから始めるべきかわかりません。私はシリアライズしてからデタップすると思っていましたが、属性がドキュメント順に処理されないので、開始と停止をどのように順番にインターリーブするのですか?頭を悩ませている間、私はあまり快適でなく、最初にシリアル化することさえ正しい戦略だった。誰かが紛失した魂に助けを提供し、コード化された失敗をした後で投稿を編集する場合には、私はさまよっていきます。 – JPM

答えて

1

...

XML入力

<trip> 
    <leg start="MA" stop="MA" /> 
    <leg start="MA" stop="CT" /> 
    <leg start="NY"   /> 
    <leg      /> 
    <leg start="DE"   /> 
    <leg   stop="DE" /> 
    <leg start="NY" stop="PA" /> 
</trip> 

XSLT 1.0

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

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

    <xsl:template match="trip"> 
    <trip> 
     <xsl:apply-templates/> 
    </trip> 
    </xsl:template> 

    <!--This is so we don't get duplicate entries 
    for both attributes when they are the same.--> 
    <xsl:template match="@stop[.=parent::*/@start]"/> 

    <xsl:template match="@start|@stop"> 
    <xsl:if test="not(parent::leg/preceding-sibling::leg[1][@start = current() or @end = current()])"> 
     <place><xsl:value-of select="."/></place>  
    </xsl:if> 
    </xsl:template> 

</xsl:stylesheet> 

XML出力

<trip> 
    <place>MA</place> 
    <place>CT</place> 
    <place>NY</place> 
    <place>DE</place> 
    <place>NY</place> 
    <place>PA</place> 
</trip> 

あなたはまた@start@stop前に処理なったことを100%確認するために、このテンプレートを追加することができます。

<xsl:template match="leg"> 
    <xsl:apply-templates select="@start"/> 
    <xsl:apply-templates select="@stop"/> 
    </xsl:template> 
+0

非常に良い。ありがとう! XSLTの学習では、start = stopをカバーするようにXSLT優先順位付けツールを使用するとはまだ考えていません。私のための良いレッスン。 +1、Qが答えました。 (元のQを元に戻してください。) – JPM

+0

大歓迎です。 +1 –

関連する問題