4

メソッド(DEST id = "RUSSIA" method = "delete" />)と彼の直接の祖先(SOURCE id = "AFRICA" )を使用して、最も深くネストされた要素ノード(XSLT、xpath、xquery ...できればxpath)を抽出する必要があります。method = "modify">)。

メソッド(main method="modify">またはmainmethod= "modify">)でトップノードを取得したくありません。

メソッドを持つ最も深いネストされた要素は、実際のアクションに対応します。メソッドの最上位の要素は、実際には考慮に入れてはならないダミーアクションです。

これが私のXMLサンプルファイルです:

<?xml version="1.0" encoding="UTF-8"?>
<main method="modify">
<MACHINE method="modify">  
  <SOURCE id="AFRICA" method="modify">
    <DEST id="RUSSIA" method="delete"/>
    <DEST id="USA" method="modify"/>
  </SOURCE>

  <SOURCE id="USA" method="modify">
    <DEST id="AUSTRALIA" method="modify"/>
    <DEST id="CANADA" method="create"/>
  </SOURCE>
</MACHINE>
</main>

これは私が期待するXpath出力です:

<SOURCE id="AFRICA" method="modify"><DEST id="RUSSIA" method="delete"/>

<SOURCE id="AFRICA" method="modify"><DEST id="USA" method="modify"/>

<SOURCE id="USA" method="modify"><DEST id="AUSTRALIA" method="modify"/>

<SOURCE id="USA" method="modify"><DEST id="CANADA" method="create"/>

現在のxpathコマンドでは適切な結果が得られません。

次を返すコマンドxpath( "// [@ method] / ancestor :: *"):

<main><MACHINE method="modify">                                        # NOT WANTED

<MACHINE method="modify"><SOURCE id="AFRICA" method="modify">          # NOT WANTED

<MACHINE method="modify"><SOURCE id="USA" method="modify">             # NOT WANTED

<SOURCE id="AFRICA" method="modify"><DEST id="RUSSIA" method="delete"/>

<SOURCE id="AFRICA" method="modify"><DEST id="USA" method="modify"/>

<SOURCE id="USA" method="modify"><DEST id="AUSTRALIA" method="modify"/>

<SOURCE id="USA" method="modify"><DEST id="CANADA" method="create"/>

追加情報(コンテキスト)の私のxmltwigコード:

#!/usr/bin/perl -w
use warnings;
use XML::Twig;
use XML::XPath;

@my $t= XML::Twig->new;
my $v= XML::Twig::Elt->new;
$t-> parsefile ('input.xml');

@abc=$t->get_xpath("\/\/[\@method]\/ancestor\:\:\*") ;
 foreach $v (@abc)   # outer 1
 {
    foreach $v ($v ->children)  # internal 1
    {
      $w=$v->parent;
      print $w->start_tag;
      print $v->start_tag;
    }
  }
4

4 に答える 4

4

最大の深さを持つノードは、

//*[count(ancestor::*) = max(//*/count(ancestor::*))]

ただし、オプティマイザーがどれほど賢いかによっては、パフォーマンスが大幅に低下する可能性があります。

それらのノードを見つけたので、それらの祖先を見つけるのはもちろん簡単です。しかし、XPath だけでは提供できない構造を持つ出力を探しています。

于 2012-06-21T11:59:58.573 に答える
1

そのような XPath2.0 式の 1 つが次のとおりです

//*[not(*)
  and
   count(ancestor::*)
  =
   max(//*[not(*)]/count(ancestor::*))
   ]
     /(self::node|..)

完全な XSLT 2.0 の例でこれを説明するには:

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

    <xsl:variable name="vResult" select=
     "//*[not(*)
        and
          count(ancestor::*)
       =
        max(//*[not(*)]/count(ancestor::*))
        ]
          /(self::node|..)
     "/>

 <xsl:template match="/">
     <xsl:sequence select="$vResult"/>
 </xsl:template>
</xsl:stylesheet>

この変換が提供された XML ドキュメントに適用されると、次のようになります。

<main method="modify">
    <MACHINE method="modify">
        <SOURCE id="AFRICA" method="modify">
            <DEST id="RUSSIA" method="delete"/>
            <DEST id="USA" method="modify"/>
        </SOURCE>
        <SOURCE id="USA" method="modify">
            <DEST id="AUSTRALIA" method="modify"/>
            <DEST id="CANADA" method="create"/>
        </SOURCE>
    </MACHINE>
</main>

XPath 式が評価され、選択された要素 (最大深度の要素とその親) が出力にコピーされます

<SOURCE id="AFRICA" method="modify">
            <DEST id="RUSSIA" method="delete"/>
            <DEST id="USA" method="modify"/>
        </SOURCE>
<SOURCE id="USA" method="modify">
            <DEST id="AUSTRALIA" method="modify"/>
            <DEST id="CANADA" method="create"/>
        </SOURCE>
于 2012-06-22T13:19:39.323 に答える
1

質問に対するコメントで述べたように、XPath には制限current()外のコンテキストを参照できる関数のようなものがないため、これは純粋な XPath では可能ではないと思います。[]

最も類似したソリューションは、次の XSLT です。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ZD="http://xyz.abc">
    <xsl:output method="text"/>

    <xsl:template match="//*">
        <xsl:choose>
            <xsl:when test="not(//*[count(ancestor::node()) > count(current()/ancestor::node())])"><xsl:value-of select="local-name(.)"/><xsl:text>
</xsl:text></xsl:when>
            <xsl:otherwise>
                <xsl:copy>
                    <xsl:apply-templates select="@*|node()"/>
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="text()|@*"/>
</xsl:stylesheet>

この<xsl:when>要素は、最も深くネストされた要素を見つけます。例として、見つかった要素のローカル名とそれに続く改行を出力していますが、もちろん必要なものは何でもそこに出力できます。

更新:これは XPath 1.0 の知識/ツールに基づいていることに注意してください。これは確かにXPath 2.0で表現できそうです。

于 2012-06-21T11:37:56.940 に答える
0

スタイルシート

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

<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
  <xsl:apply-templates 
     select="//DEST[@method and not(node())]"/>
</xsl:template>

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* , node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="DEST[@method and not(node())]">
  <xsl:apply-templates select="..">
    <xsl:with-param name="leaf" select="current()"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="*[DEST[@method and not(node())]]">
  <xsl:param name="leaf"/>
  <xsl:copy>
    <xsl:copy-of select="@* , $leaf"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

変形する

<?xml version="1.0" encoding="UTF-8"?>
<main method="modify">
<MACHINE method="modify">  
  <SOURCE id="AFRICA" method="modify">
    <DEST id="RUSSIA" method="delete"/>
    <DEST id="USA" method="modify"/>
  </SOURCE>

  <SOURCE id="USA" method="modify">
    <DEST id="AUSTRALIA" method="modify"/>
    <DEST id="CANADA" method="create"/>
  </SOURCE>
</MACHINE>
</main>

の中へ

<SOURCE id="AFRICA" method="modify">
   <DEST id="RUSSIA" method="delete"/>
</SOURCE>
<SOURCE id="AFRICA" method="modify">
   <DEST id="USA" method="modify"/>
</SOURCE>
<SOURCE id="USA" method="modify">
   <DEST id="AUSTRALIA" method="modify"/>
</SOURCE>
<SOURCE id="USA" method="modify">
   <DEST id="CANADA" method="create"/>
</SOURCE>
于 2012-06-21T10:43:03.207 に答える