2012-04-04 7 views
3

要素の子要素の属性値のリストを取得しようとしましたが、値が1回しか表示されないようにします。要素ごとにXSLTで不利益を選択

たとえば、私は、次のXML

<root> 
    <sec> 
     <nom-title> 
      <nom-chapter> 
       <nom-article><data att="1.1"/></nom-article> 
       <nom-article> 
        <nom-item><data att="1.1"/></nom-item> 
        <nom-item><data att="1.2"/></nom-item> 
       </nom-article> 
      </nom-chapter> 
      <nom-chapter> 
       <nom-article><data att="2.1"/></nom-article> 
       <nom-article><data att="1.1"/></nom-article> 
      </nom-chapter> 
     </nom-title> 
     <nom-title> 
      <nom-chapter> 
       <nom-article><data att="1.1"/></nom-article> 
      </nom-chapter> 
     </nom-title> 
    </sec> 
</root> 

を持っていると私はそのような結果たい:私はXSLを使用しようとした

<root> 
    <nom-title> 
     <att>1.1</att> 
     <att>1.2</att> 
     <att>2.1</att> 
     <nom-chapter> 
      <att>1.1</att> 
      <att>1.2</att> 
      <nom-article> 
       <att>1.1</att> 
      </nom-article> 
      <nom-article> 
       <att>1.1</att> 
       <att>1.2</att> 
       <nom-item><att>1.1</att></nom-item> 
       <nom-item><att>1.2</att></nom-item> 
      </nom-article> 
     </nom-chapter> 
    </nom-title> 
    <nom-title> 
     <att>1.1</att> 
     <nom-chapter> 
      <att>1.1</att> 
      <nom-article> 
       <att>1.1</att> 
      </nom-article> 
     </nom-chapter> 
    </nom-title> 
</root> 

を:重要な要素を、それだけを返します1つの要素の値。この例では、最初のタイトルは1.1を返しますが、2番目のタイトルは返しません。私が使用したのxsl:

<xsl:key name="allAtt" 
    match="//*[starts-with(name(.),'nom-')]/data" 
    use="@att"/> 
<xsl:template match="nom-title|nom-chapter|nom-article|nom-item"> 
    <xsl:element name="name(.)"> 
     <xsl:apply-templates select=".//*[starts-with(name(.),'nom-')]/data 
    </xsl:element> 
</xsl:template>   
<xsl:template match="data"> 
     <xsl:variable name="att" select="@att"/> 
     <xsl:if test="generate-id(.)=generate-id(key('allAtt',$att)[1]"> 
      <xsl:element name="att"><xsl:value-of select="$att"></xsl:element> 
     </xsl:if> 
</xsl:template> 
+2

xsltでの私の経験では、まず有効なxmlが必要です。 「nom-article」要素が閉じられていないように見えます。まずそれを修正しようとしたいかもしれません。 –

+1

私はJustinに同意します。適切なXML入力サンプルを最初に表示してください。現在、入力の構造は明確ではなく、いくつかのタグが正しく閉じられていません(例: ''、 ' ')。 –

+0

申し訳ありませんが、間違ったコピー貼り付け、私はそれを修正しました。 – claudex

答えて

2

この変換

<root> 
    <sec> 
     <nom-title> 
      <nom-chapter> 
       <nom-article> 
        <data att="1.1"/> 
       </nom-article> 
       <nom-article> 
        <nom-item> 
         <data att="1.1"/> 
        </nom-item> 
        <nom-item> 
         <data att="1.2"/> 
        </nom-item> 
       </nom-article> 
      </nom-chapter> 
      <nom-chapter> 
       <nom-article> 
        <data att="2.1"/> 
       </nom-article> 
       <nom-article> 
        <data att="1.1"/> 
       </nom-article> 
      </nom-chapter> 
     </nom-title> 
     <nom-title> 
      <nom-chapter> 
       <nom-article> 
        <data att="1.1"/> 
       </nom-article> 
      </nom-chapter> 
     </nom-title> 
    </sec> 
</root> 

を指名手配、正しい結果を生成します。提供されるXML文書に適用

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

<xsl:key name="kData-nom-article" match="data" use= 
"concat(generate-id(ancestor::nom-article[1]), 
     '+', @att)"/> 
<xsl:key name="kData-nom-chapter" match="data" use= 
"concat(generate-id(ancestor::nom-chapter[1]), 
     '+', @att)"/> 
<xsl:key name="kData-nom-title" match="data" use= 
"concat(generate-id(ancestor::nom-title[1]), 
     '+', @att)"/> 

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

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

<xsl:template match="nom-title|nom-article|nom-chapter"> 
    <xsl:copy> 
    <xsl:apply-templates mode="list" select= 
    ".//data[generate-id() 
      = 
       generate-id(key(concat('kData-', name(current())), 
           concat(generate-id(current()), 
            '+', @att 
            ) 
          ) 
           [1] 
         ) 
      ]"/> 
    <xsl:apply-templates/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="data" mode="list"> 
    <att><xsl:value-of select="@att"/></att> 
</xsl:template> 

<xsl:template match="non-item/data"> 
    <att><xsl:value-of select="@att"/></att> 
</xsl:template> 

<xsl:template match="*[not(self::nom-item)]/data"/> 
</xsl:stylesheet> 

<root> 
    <nom-title> 
     <att>1.1</att> 
     <att>1.2</att> 
     <att>2.1</att> 
     <nom-chapter> 
     <att>1.1</att> 
     <att>1.2</att> 
     <nom-article> 
      <att>1.1</att> 
     </nom-article> 
     <nom-article> 
      <att>1.1</att> 
      <att>1.2</att> 
      <nom-item> 
       <data att="1.1"/> 
      </nom-item> 
      <nom-item> 
       <data att="1.2"/> 
      </nom-item> 
     </nom-article> 
     </nom-chapter> 
     <nom-chapter> 
     <att>2.1</att> 
     <att>1.1</att> 
     <nom-article> 
      <att>2.1</att> 
     </nom-article> 
     <nom-article> 
      <att>1.1</att> 
     </nom-article> 
     </nom-chapter> 
    </nom-title> 
    <nom-title> 
     <att>1.1</att> 
     <nom-chapter> 
     <att>1.1</att> 
     <nom-article> 
      <att>1.1</att> 
     </nom-article> 
     </nom-chapter> 
    </nom-title> 
</root> 

説明:動的に実行される実際のグループ化のためのキーの名前を構築することによって、一つとして、三つの異なるMuenchianグルーピングを発現します。

注意:キー名は、ストリングと、必要な場合(この場合のように)であり、名前は動的に構築、またはパラメータとして渡すことができます。