1

これは何度も投稿されたよくある質問の 1 つであることは理解していますが、残念ながら、提案されたアプローチのいずれでも正確な解決策を見つけることができません。

私のXMLは次のようになります。

<root>
  <parent>
    <table>
    <attr ......>
       <type t="enumone">
       <info>
        <name .....>
       </info>
    </attr>

    <attr>
        <type t="int">
        <range min="1" max="255"/>
         </type>
         <info>
        <name .....>
       </info>
    </attr>

    <attr>
        <type t="string">
         <info>
        <name .....>
       </info>
    </attr> 
    <attr ......>
       <type t="enumtwo">
       <info>
        <name .....>
       </info>
    </attr>

    <attr>
        <type t="float">
        <range min="1.0" max="25.5"/>
         </type>
         <info>
        <name .....>
       </info>
    </attr>

    <attr>
        <type t="int">
         <info>
        <name .....>
       </info>
    </attr> 


    <attr>
        <type t="enumone">
         <info>
        <name .....>
       </info>
    </attr> 
    <attr>
        <type t="enumthree">
         <info>
        <name .....>
       </info>
    </attr> 
    <attr>
        <type t="enumone">
         <info>
        <name .....>
       </info>
    </attr> 
    </parent>
 </root>

XSLT を使用して、"type" 要素から属性 "@t" の 1 つのオカレンスを取得することを意図しています。

Using for-each-group:
<xsl-template match="/root/parent">
  <xsl:for-each select="table">
    <xsl:for-each-group select="//type" group-by="@t">
       <xsl:copy-of select="current-group( )[1]"/>
    </xsl:for-each-group>
  </xsl:for-each>
<xsl-template>

しかし、私は出力を得ませんでした!何か欠陥があると思います。

個別値 () の使用:

<xsl:for-each select="distinct-values(type/@t)">
<xsl:sort/>
<xsl:value-of select="."/> <xsl:call-template name="newline"/>
</xsl:for-each>

まだ望ましい出力はありません。

予想される出力は次のとおりです。

enumone
int
string
enumtwo
float
enumthree

この点で何か助けていただければ幸いです。

4

2 に答える 2

2

入力サンプルは整形式の XML ではありませんが、本当にすべての要素の個別のt属性値だけが必要な場合は、次のようにします。type

<xsl:template match="/">
  <xsl:value-of select="distinct-values(//type/@t)" separator="&#10;"/>
</xsl:template>

XSLT 2.0 で十分です。

さらに個別の値を並べ替えたい場合は、

<xsl:template match="/">
  <xsl:value-of separator="&#10;">
    <xsl:perform-sort select="distinct-values(//type/@t)">
       <xsl:sort select="."/>
    </xsl:perform-sort>
  </xsl:value-of>
</xsl:template>

完全な例を挙げると、入力は

<root>
  <foo>
    <type t="int"/>
  </foo>
  <bar>
    <type t="enum"/>
  </bar>
  <foobar>
     <foo>
        <type t="enum">
           <x/>
        </type>
     </foo>
   </foobar>
   <foo>
      <type t="string"/>
   </foo>
</root>

スタイルシート

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

<xsl:output method="text"/>

<xsl:template match="/">
  <xsl:value-of separator="&#10;">
    <xsl:perform-sort select="distinct-values(//type/@t)">
       <xsl:sort select="."/>
    </xsl:perform-sort>
  </xsl:value-of>
</xsl:template>

</xsl:stylesheet>

出力

enum
int
string
于 2012-08-03T09:39:45.107 に答える
0

コードを次のように変更するだけです:

<xsl:template match="/">
    <xsl:for-each-group select="//type" group-by="@t">
       <xsl:copy-of select="current-group( )[1]"/>
    </xsl:for-each-group>
</xsl:template>

完全な変換:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:template match="/">
    <xsl:for-each-group select="//type" group-by="@t">
       <xsl:copy-of select="current-group( )[1]"/>
    </xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>

整形式の XML ドキュメントに適用した場合:

<root>
  <foo>
    <type t="int"/>
  </foo>
  <bar>
    <type t="enum"/>
  </bar>
  <foobar>
     <foo>
        <type t="enum">
           <x/>
        </type>
     </foo>
   </foobar>
   <foo>
      <type t="string"/>
   </foo>
</root>

正しい結果が生成されます。

<type t="int"/>
<type t="enum"/>
<type t="string"/>
于 2012-08-03T14:37:31.000 に答える