0

特定のノードの子孫から(idを介して)参照されているが、特定のノード自体の子孫ではない、xmlドキュメントからすべてのノードを取得するための再利用可能な方法を探しています。例えば:

<root>
  <somenode>
     <a id="a1"/>
     <aref ref="a1"/>
  </somenode>
  <somenode>
     <a id="a2"/>
     <aref ref="a1"/>
     <aref ref="a2"/>
  </somenode>
</root>

指定されたノードが/root/ somenode [1]の場合、結果のノードセットは空になります。参照されるすべてのaは、/ root /somenode[1]の子です。一方、指定されたノードが/ root / somenode [2]の場合、結果のノードセットには/ root / somenode [1] /a[1]のみが含まれる必要があります。

結果のノードセットが常に同じ方法でソートされることが重要です。また、ソリューションではxslt-1.0のみを使用し、exlst拡張機能をxsltprocに組み込む必要があります(ライブラリの正確なバージョン:「libxml20708、libxslt 10126、およびlibexslt815の使用」)

よろしくお願いします、Jost

4

2 に答える 2

1

ここで提供されるソリューションは、拡張機能を使用せず、XSLTプロセッサで100%移植可能です。

xslt関数の使用generate-id()

//*[@id = /*/somenode[1]/aref/@ref 
  and 
    not(generate-id(ancestor::somenode) = generate-id(/*/somenode[1]))
   ]

キーを使用すると、効率が向上する可能性があります。

これは、ノードセットの共通部分のKayessian式を使用して、単一のXPath1.0式として表現することもできます。

$ns1[count(.|$ns2) = count($ns2)]

純粋なXPath2.0では、のis代わりに演算子を使用しgenerate-id()ます。

これが完全なデモです:

<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:template match="/">
  "<xsl:copy-of select=
   "//*[@id = /*/somenode[1]/aref/@ref
      and
        not(generate-id(ancestor::somenode) = generate-id(/*/somenode[1]))
       ]"/>"
============
  "<xsl:copy-of select=
   "//*[@id = /*/somenode[2]/aref/@ref
      and
        not(generate-id(ancestor::somenode) = generate-id(/*/somenode[2]))
        ]"/>"
 </xsl:template>
</xsl:stylesheet>

この変換が提供されたXMLドキュメントに適用される場合:

<root>
  <somenode>
     <a id="a1"/>
     <aref ref="a1"/>
  </somenode>
  <somenode>
     <a id="a2"/>
     <aref ref="a1"/>
     <aref ref="a2"/>
  </somenode>
</root>

XPath式が評価され、選択したノードが出力にコピーされます。

  ""
============
  "<a id="a1" />"
于 2012-07-27T14:33:06.783 に答える
1

http://www.exslt.org/set/functions/difference/index.htmlによると、libxsltはその関数をサポートしています。

<xsl:key name="el-by-id" match="*" use="id"/>

<xsl:variable name="refs" select="set:difference(key('el-by-id', descendant::*/@ref), descendant::*)"/>

xmlns:set="http://exslt.org/sets"あなたのノードがコンテキストノードであるテンプレートで(で)行う必要があります。

于 2012-07-27T14:35:08.420 に答える