2009-06-03 12 views
1

以前の一意の「ROLE」ノードを数え、次の出力形式のROLE/@ name、PERM/@ perfrom、および数を出力するXSLスタイルシートを適用したい現在のノードより前の一意のROLEノード
これはthis questionから続きますが、もう少し複雑です。 Muenchianメソッドは、このファイルの長さが大きくなるため、これを実装する最善の方法だと思います。XSL:子ノードから以前の一意の兄弟を数える

私はここ(長さについて申し訳ありません)、次のXML

<?xml version="1.0" encoding="utf-8" ?> 
<ROLEACTIONINFO> 
    <ROLE name="TESTER"> 
    <ACTIONINFO> 
     <PERMINFO> 
     <PERM type="PT0" field="ALL" permfrom="PERM1565"/> 
     </PERMINFO> 
    </ACTIONINFO> 
    </ROLE> 
    <ROLE name="PARENT1"> 
    <ACTIONINFO> 
    </ACTIONINFO> 
    </ROLE> 
    <ROLE name="PARENT1"> 
    <ACTIONINFO> 
     <PERMINFO> 
     <PERM type="PT8" field="ALL" permfrom="PERM1"/> 
     </PERMINFO> 
    </ACTIONINFO> 
    </ROLE> 
    <ROLE name="PARENT1"> 
    <ACTIONINFO> 
     <PERMINFO> 
     <PERM type="PT7" field="ALL" permfrom="PERM2"/> 
     <PERM type="PT7" field="ALL" permfrom="PERM54"/> 
     </PERMINFO> 
    </ACTIONINFO> 
    </ROLE> 
    <ROLE name="PARENT2"> 
    <ACTIONINFO> 
     <PERMINFO> 
     <PERM type="PT6" field="ALL" permfrom="PERM1"/> 
     </PERMINFO> 
    </ACTIONINFO> 
    </ROLE> 
    <ROLE name="PARENT2"> 
    <ACTIONINFO> 
     <PERMINFO> 
     <PERM type="PT5" field="ALL" permfrom="PERM2"/> 
     </PERMINFO> 
    </ACTIONINFO> 
    </ROLE> 
    <ROLE name="PARENT3"> 
    <ACTIONINFO> 
     <PERMINFO> 
     <PERM type="PT2" field="ALL" permfrom="PERM44"/> 
     </PERMINFO> 
    </ACTIONINFO> 
    </ROLE> 
</ROLEACTIONINFO> 

を持っているが、私は一緒に遊んでされているバージョンのXSLシートである:

:ここ

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:template match="text()"/> 

    <xsl:key name="kRole" match="ROLE[ACTIONINFO/PERMINFO/PERM]" use="@name" /> 

    <xsl:template match="PERM"> 
    <xsl:variable name="roles-so-far" select="ancestor::ROLE | ancestor::ROLE/preceding-sibling::ROLE[ACTIONINFO/PERMINFO/PERM]"/> 
    <!-- Only select the first instance of each ROLE name --> 
    <xsl:variable name="roles-so-far-unique"    
        select="$roles-so-far[generate-id(ancestor::ROLE) = generate-id(key('kRole',ancestor::ROLE/@name)[1])]"/> 
    <xsl:apply-templates select="ancestor::ROLE/@name"/> 
    <xsl:text>&#x9;</xsl:text> 
    <xsl:apply-templates select="@permfrom"/> 
    <xsl:text>&#x9;</xsl:text> 
    <xsl:value-of select="count($roles-so-far-unique)"/> 
    <!-- linefeed --> 
    <xsl:text>&#xA;</xsl:text> 
    </xsl:template> 

</xsl:stylesheet> 

は、所望の出力であります

TESTER PERM1565 1 
PARENT1 PERM1 2 
PARENT1 PERM2 2 
PARENT1 PERM54 2 
PARENT2 PERM1 3 
PARENT2 PERM2 3 
PARENT3 PERM44 4 

実際の(誤った)出力は次のとおりです。

TESTER PERM1565 1 
PARENT1 PERM1 2 
PARENT1 PERM2 3 
PARENT1 PERM54 3 
PARENT2 PERM1 4 
PARENT2 PERM2 5 
PARENT3 PERM44 6 

ありがとうございます。

+0

第3の「PARENT1」には2つのがありますが、最初には何もありませんか?男、あなたはこの入力データをどこから得ますか? :)とにかく、私はカウントが等しいと仮定し、あなたはそれらがバランスを取るようにします。これがあなたの側のタイプミスであった場合、私のソリューションはよりシンプルになります。 – Tomalak

+0

私は変更された解決策を掲示しました。それを確認してください、私はこれがあなたが探しているものだと思います。 – Tomalak

答えて

1

これは応じ<ROLE>を取り、それが独特の前任者だ数え、あらゆる<PERM>から行く:

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

    <xsl:output method="text" /> 

    <xsl:variable name="TAB" select="'&#x09;'" /> 
    <xsl:variable name="LF" select="'&#x0A;'" /> 

    <xsl:key name="kRole" match="ROLE" use="@name" /> 

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

    <xsl:template match="PERM"> 
    <xsl:variable name="vThisRole" select="ancestor::ROLE[1]" /> 
    <xsl:variable name="vPrecedingRoles" select=" 
     ($vThisRole | $vThisRole/preceding-sibling::ROLE) 
    " /> 
    <xsl:variable name="vUniquePrecedingRoles" select=" 
     $vPrecedingRoles[count(. | key('kRole', ./@name)[1]) = 1] 
    " /> 
    <xsl:value-of select=" 
     concat(
     $vThisRole/@name, $TAB, 
     @permfrom, $TAB, 
     count($vUniquePrecedingRoles), $LF 
    ) 
    " /> 
    </xsl:template> 

</xsl:stylesheet> 

出力:

 
TESTER PERM1565  1 
PARENT1 PERM1 2 
PARENT1 PERM2 2 
PARENT1 PERM54 2 
PARENT2 PERM1 3 
PARENT2 PERM2 3 
PARENT3 PERM44 4 

あなたが扱っているXMLはかなり悪い形であり、場合あなたは私に尋ねる。少なくとも、適切なデータ構造ではなく、セキュリティ関連のものが「先行する固有名詞の数」によって表されるという事実は、私の頭を傷つける。 ;-)あなたは入力を変更することができますか?

+0

これは前任者の質問に投稿された私の回答の変形です:http://stackoverflow.com/questions/941662/xsl-counting-previous-unique-siblings/944544#944544より広範な説明があります。 – Tomalak

+0

私は入力や出力を変えることはできません。 (はい、それは醜いです)入力はいくつかのレガシーシステムから来ており、出力は棚のシステム外に送られています。 XMLは実際にはTABで区切られた出力と比較してステップアップされています:)少なくとも、データ長/文字フォーマットなどをXMLデータで検証することはできません。 私はROLEノードの作業フォームがこのトリックを行うつもりであるとは確信していませんが、私はあなたにお知らせします。 ありがとうございました – Jay

+0

私の質問を再確認するには...実際には2つのバランスが取れているのか、それともROLE-PERMの配下にいくつかの他のロジックがありますか? – Tomalak