2

任意のXMLドキュメントで使用できるXSLTドキュメントを作成し、結果をHTMLテーブルに表示する必要があります。テーブルの列はすべて、XMLドキュメントにあるタグの数によって異なります。使おうとしていた

<xsl:value-of select="count(/*/*/)"/> 

タグの数を数えます。

しかし、たとえば私が持っている場合、私はそれが欲しいです:

  <film>
      <title></title>
      <year></year>
      <actor></actor>
  </film>
  <film>
      <title></title>
      <year></year>
      <actor></actor>
  </film>

結果は、現在表示されている6ではなく3になります。この問題の解決策はありますか?

4

3 に答える 3

1

I.仮定

  1. 次のような整形式のXMLドキュメントがあること。

。。。。

<films>
  <film>
    <title/>
    <year/>
    <actor/>
  </film>
  <film>
    <title/>
    <year/>
    <actor/>
  </film>
</films>

および

.2。すべてのfilm要素に同じ数の同じ名前の列がある場合、必要なのは次のとおりです。

 count(/*/*[1]/*)

これにより、XMLドキュメントの最上位要素の最初の子要素の子要素の数が生成されます

3

II。別の可能性:film要素が異なれば子の数も異なり、そのうちの1つには、テーブルの列の総数を決定するすべての子があります

<films>
  <film>
    <title/>
    <year/>
    <actor/>
  </film>
  <film>
    <title/>
    <year/>
    <actor/>
    <rating/>
    <director/>
  </film>
  <film>
    <title/>
    <year/>
    <actor/>
    <rating/>
  </film>
</films>

次に、XPath 2.0を使用して、次を使用します。

max(/*/*/count(*))

これにより、XMLドキュメントの最上位要素の子が持つ子の最大数が生成されます。

5

III。film最後に、どの要素にも列のすべての要素が含まれていない可能性がある場合は、(ABachがすでに提案したもの)を使用します。

count(distinct-values(/*/*/*/name()))
于 2012-11-18T03:37:40.673 に答える
0

I. XSLT 1.0 / XPath 1.0

純粋なXPath1.0でこれを行う方法はないと思います(特定の順序ではないと思います[とにかく、そこに依存するのは好きではありません)。ある種の秩序である])。

そうは言っても、キーベースのXSLT1.0ソリューションを使用して問題を解決できます。

このXSLT1.0ドキュメントの場合:

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

  <xsl:key name="kFilmChildren" match="film/*" use="name()"/>

  <xsl:template match="/">
    <xsl:value-of
      select="count(//film/*[
                generate-id() = 
                generate-id(key('kFilmChildren', name())[1])
      ])"/>
  </xsl:template>
</xsl:stylesheet>

...サンプルXML(ルート要素にラップされている)に対して適用されます:

<films>
  <film>
    <title/>
    <year/>
    <actor/>
  </film>
  <film>
    <title/>
    <year/>
    <actor/>
  </film>
</films>

...必要な結果が生成されます:

3

わずかに変更されたXMLに対して同じスタイルシートを適用する場合:

<films>
  <film>
    <title/>
    <year/>
    <actor/>
    <test/>
  </film>
  <film>
    <title/>
    <year/>
    <actor/>
    <test/>
    <test2/>
  </film>
</films>

...繰り返しますが、正しい答えが生成されます:

5

注:完全なドキュメントを表示しなかったため、//式を使用して、不足している知識を補いました。ただし、これは非常に大きな木の根元近くでの費用のかかる操作になる可能性があります。あなたはあなたをより具体的にするためにうまくいくでしょう。


II。XSLT 2.0 / XPath 2.0

distinct-valuesPure XPath 2.0を使用すると、次の式を使用して正しい答えを得ることができます。

count(distinct-values(//film/*/name()))

XSLT検証:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output omit-xml-declaration="no" indent="yes" method="text" />
  <xsl:strip-space elements="*" />

  <xsl:template match="/">
     <xsl:value-of select="count(distinct-values(//film/*/name()))" />
  </xsl:template>

</xsl:stylesheet>

結果:

3
于 2012-11-18T02:19:54.563 に答える
0

ドキュメントには、実際には16個のタグが含まれています。8個の開始タグと8個の終了タグです。したがって、「タグを数える」ことはあなたの本当の要件ではないと思います。あなたの用語が間違っているので、私たちはあなたの本当の要件を推測することしかできません。個別の要素名ごとに1行で、その名前の要素の数を含むテーブルを作成することになるのではないかと思います。これは:

<table>
  <xsl:for-each-group select="//*" group-by="name()">
    <tr>
      <td><xsl:value-of select="current-grouping-key()"/></td>
      <td><xsl:value-of select="count(current-group()"/></td>
    </tr>
  </xsl:for-each-group>
</table>
于 2012-11-18T08:34:47.150 に答える