1

こんにちは私はxmlを初めて使用し、xslスタイルシートを使用していくつかの値を比較したいと思います

`<a>
 <b>   <name>foo</name>   </b>
 <b>   <name>bar</name>   </b>
 <b>   <name>fred</name>  </b>
 <b>   <name>fred</name>  </b>
 </a>`

すべてのbノードをチェックし、同じ値を持つ値を返すスタイルシートを作成したいので、上記の簡単な例を使用して、出力を次のようにします。
「重複する文字列はフレッドです」

for eachループを使用してすべての値を返しましたが、名前を比較して重複を返すことはできませんでした。可能であれば、whileタイプのループを使用して比較を行いたいと思います。

助けてくれてありがとう。

4

3 に答える 3

2

XSLT 1.0:キーを使用したシンプルなソリューション

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:key name="kNameByVal" match="name" use="."/>

 <xsl:template match="/*">
  Your duplicate strings are: <xsl:text/>

  <xsl:apply-templates select=
    "b/name[generate-id() = generate-id(key('kNameByVal', .)[2])]"/>
 </xsl:template>

 <xsl:template match="name">
  <xsl:if test="position() >1">, </xsl:if>
  <xsl:value-of select="."/>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

II。XSLT 2.0ソリューション

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:variable name="vSeq" select="data(/a/b/name)"/>

 <xsl:template match="/">
  Your duplicate strings are: <xsl:text/>
  <xsl:sequence select="$vSeq[index-of($vSeq,.)[2]]"/>
 </xsl:template>
</xsl:stylesheet>

III。XPath2.0ワンライナー

$vSeq[index-of($vSeq,.)[2]]

これにより、重複(重複のグループからの1つ)を持つ、指定されたシーケンス内のすべての値が生成されます。

于 2012-07-21T20:30:35.310 に答える
1

whileループの使用は、実行可能であっても、XSLTの哲学に反します。

あなたが望むことをするためのもっと簡単な方法がいくつかあります、例えば:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method='text' />
<xsl:template match="b">
   <xsl:if test='preceding::b/name/text()=./name/text()'>
Your duplicate is: <xsl:copy-of select='./name/text()' />
   </xsl:if>
</xsl:template>

</xsl:stylesheet>

これはノードbを探しており、前のbノードが同じ名前のテキストを持っているかどうかをチェックしています

于 2012-07-21T19:40:04.747 に答える
1

ベースの<xsl:key>ソリューション:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:key name="kName" match="b/name" use="text()" />

  <xsl:template match="/">
    <xsl:for-each select="//b/name">
      <xsl:if test="count(key('kName', text())) &gt; 1">
        <xsl:value-of select="concat('Your duplicate is: ', text(), '&#xA;')" />
      </xsl:if>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

preceding::大きな入力ドキュメントの場合、これはチェックを使用するソリューションよりも効率的です。

于 2012-07-21T19:53:46.330 に答える