ここにXSLT 2.0メソッドがあります。
には、スキャンするドキュメントノードのシーケンスが含まれていると仮定し、ドキュメントに表示される各要素に対して1行を作成するとします。あなたはそれを行うために<xsl:for-each-group>
を使用することができます。
<xsl:for-each-group select="$docs//*" group-by="name()">
<xsl:sort select="current-group-key()" />
<xsl:variable name="name" as="xs:string" select="current-grouping-key()" />
<xsl:value-of select="$name" />
...
</xsl:for-each-group>
その後、あなたは文書の中で、その要素の統計情報を知りたいです。今
<xsl:variable name="elem-counts" as="xs:integer+"
select="$docs-with/count(//*[name() = $name])" />
そして:
<xsl:variable name="docs-with" as="document-node()+"
select="$docs[//*[name() = $name]" />
第二に、あなたは文書のそれぞれにその名前の要素数のシーケンスを必要とする:まず、文書はその中にその名前の要素を持っている見つけますあなたは計算を行うことができます。平均、最小および最大は、avg()
,min()
およびmax()
関数で計算できます。パーセンテージは、単純に要素を含む文書の数を、文書の総数で割った値です。それを一緒に置く
:
<xsl:for-each-group select="$docs//*" group-by="name()">
<xsl:sort select="current-group-key()" />
<xsl:variable name="name" as="xs:string" select="current-grouping-key()" />
<xsl:variable name="docs-with" as="document-node()+"
select="$docs[//*[name() = $name]" />
<xsl:variable name="elem-counts" as="xs:integer+"
select="$docs-with/count(//*[name() = $name])" />
<xsl:value-of select="$name" />
<xsl:text>* </xsl:text>
<xsl:value-of select="format-number(avg($elem-counts), '#,##0.0')" />
<xsl:text> </xsl:text>
<xsl:value-of select="format-number(min($elem-counts), '#,##0')" />
<xsl:text> </xsl:text>
<xsl:value-of select="format-number(max($elem-counts), '#,##0')" />
<xsl:text> </xsl:text>
<xsl:value-of select="format-number((count($docs-with) div count($docs)) * 100, '#0')" />
<xsl:text>%</xsl:text>
<xsl:text>
</xsl:text>
</xsl:for-each-group>
を私はここに行っていない何が要素の深さに応じて行をインデントされます。私はちょうどあなたに統計を与えるためにアルファベット順に要素を注文しました。その理由は2つあります。第1に、異なる文書が異なる構造を持つため、要素統計を文書にどのように表示するかを反映する何らかの構造で要素統計を表示することは、はるかに難しくなります。第2に、多くのマークアップ言語では、文書の正確な構造を知ることができません(たとえば、セクションが任意の深さまでセクション内にネストできるため)。
私はそれが役に立たないことを望みます。
UPDATE:
は、XSLTのラッパーとXSLTを実行するためのいくつかの命令が必要ですか? OK。まず、Saxon 9Bに手をつけてください。
分析するすべてのファイルをディレクトリに配置する必要があります。 Saxonでは、special URI syntaxを使用するコレクションを使用して、そのディレクトリ(またはそのサブディレクトリ)内のすべてのファイルにアクセスできます。再帰的に検索したり、ファイル名で見ているファイルをフィルタリングする場合は、その構文を調べることをお勧めします。今
フルXSLT:これはdir
を設定するために、main
という名前のテンプレートを使用してプロセスを開始するためにサクソンを伝え
> java -jar path/to/saxon.jar -it:main -o:report.txt dir=file:///path/to/your/directory?select=*.xml
:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:param name="dir" as="xs:string"
select="'file:///path/to/default/directory?select=*.xml'" />
<xsl:output method="text" />
<xsl:variable name="docs" as="document-node()*"
select="collection($dir)" />
<xsl:template name="main">
<xsl:for-each-group select="$docs//*" group-by="name()">
<xsl:sort select="current-group-key()" />
<xsl:variable name="name" as="xs:string" select="current-grouping-key()" />
<xsl:variable name="docs-with" as="document-node()+"
select="$docs[//*[name() = $name]" />
<xsl:variable name="elem-counts" as="xs:integer+"
select="$docs-with/count(//*[name() = $name])" />
<xsl:value-of select="$name" />
<xsl:text>* </xsl:text>
<xsl:value-of select="format-number(avg($elem-counts), '#,##0.0')" />
<xsl:text> </xsl:text>
<xsl:value-of select="format-number(min($elem-counts), '#,##0')" />
<xsl:text> </xsl:text>
<xsl:value-of select="format-number(max($elem-counts), '#,##0')" />
<xsl:text> </xsl:text>
<xsl:value-of select="format-number((count($docs-with) div count($docs)) * 100, '#0')" />
<xsl:text>%</xsl:text>
<xsl:text>
</xsl:text>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
そして、それを実行するようにあなたが何かをするだろうパラメータをfile:///path/to/your/directory?select=*.xml
に設定し、出力をreport.txt
に送信します。
Jeni、あなたのサイトがXPathの大きな課題に私を助けてくれたので、私はあなたの大ファンです。 StackOverflowでここに参加してくれてうれしいです。 –
あなたのアップデートを見ました - 今すぐ入手できます:) –