2

next_siblingまたはfirst_eltを介して次のノードを選択する必要があります。しかし、ノード名でフィルタリングしたい (文字列"TON"を含む)

first_elt ('HILTON[@method]' or 'SHERATON[@method]');

また

next_sibling ('HILTON[@method]' or 'SHERATON[@method]');

また

next_sibling ('TON[@method]');

私が試した例(動作していません):

#!/usr/bin/perl -w
use warnings;
use XML::Twig;
$t-> parsefile ('file.xml');

my $Y0=$t->first_elt('HILTON[@method]' or 'SHERATON[@method]');

「HILTON[@method]」のみを処理します

my $Y0=$t->first_elt('/*TON[@method]');

C:/strawberry/perl/site/lib/XML/Twig.pm 行 3523 の間違ったナビゲーション条件 '/*TON[@method]' ()

4

2 に答える 2

3

これは XML::Twig でサポートされている XPath サブセットの外にあるため、次のコードを渡すことによって、カスタム フィルターを使用する必要がありますfirst_elt

$t->first_elt( sub {  $_[0]->tag=~ m{TON$} && $_[0]->att( 'method') })

これは、サブルーチンが真の値を返す最初の要素を返します。

しかし、そのような表現の必要性は少し厄介です。あなたの例では、要素の名前が TON で終わるという事実によって、要素のクラスを定義します。CARLTON 要素があるとどうなりますか? または、いつ MARRIOTT 要素を SHERATON と HILTON で処理する必要がありますか? クエリを書き直す必要がありますか?

データのフォーマットを設計している場合は、フォーマットを修正することをお勧めします。HILTON および SHERATON は、おそらく、HOTEL、BRAND、または OWNER タグの属性である必要があります。両方のタイプを同様に処理する必要があることを示すために、追加の属性が役立つ場合があります。この属性は、データ固有のプロパティである場合にのみ意味があります。

データがそのままで、その形式について入力がない場合は、処理するタグのリストがあり、これらを確認します。

my %TAGS_TO_PROCESS= map { $_ => 1 } qw( HILTON SHERATON);
my $elt= $t->first_elt( sub {  $TAGS_TO_PROCESS{$_[0]->tag} && $_[0]->att( 'method') })

このように、他のタグの追加/削除は簡単です。

于 2012-07-05T05:04:42.390 に答える
2

使用:

*[substring(name(), string-length(name()) - 2) = 'TON'][@method][1]

説明:

この式は、XPath 2.0 標準関数に相当する XPath 1.0 を使用しますends-with()

XPath 2.0 式に相当する XPath 1.0 は次のとおりです。

ends-with($s, $s2)

:

substring($s, string-lenth() - string-length($s2) + 1) = $s2

この最後の式では$sname()$s2を置き換えます'TON'

XSLT ベースの検証:

<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=
     "*[substring(name(), string-length(name()) - 2) = 'TON'][@method] "/>
==========  
     <xsl:copy-of select=
     "*[substring(name(), string-length(name()) - 2) = 'TON'][@method][1] "/>
 </xsl:template>
</xsl:stylesheet>

この XML ドキュメントに適用すると:

<t>
 <HILTON method="buy"/>
 <TON method="burn"/>
 <TONIC method="drink"/>
 <HILTON nomethod="yes"/>
 <SHERATON/>
 <SHERATON method="visit"/>
</t>

変換によって 2 つの XPath 式が評価され、選択されたノードが出力にコピーされます

<HILTON method="buy"/>
<TON method="burn"/>
<SHERATON method="visit"/>
==========  
     <HILTON method="buy"/>

最初の式は、名前が「TON」で終わり、method属性を持つコンテキスト ノードの子であるすべての要素を選択します。

2 番目の式は、最初の式で選択されたノードから最初のノードを選択します。

于 2012-07-04T21:31:48.253 に答える