各入力要素を出力するXPath関数を表現する方法は?

各入力要素を出力するXPath関数を表現する方法は?

私は次のコマンドを使用しています:

xmllint --xpath 'substring-after(string(//item/link), "_")' rss.xml

希望の出力を取得しますが、最初の要素にあります。この問題をそれぞれに適用するにはどうすればよいですかlink

サンプル入力を許可し、式を使用して目的の出力を取得できるすべてのユーティリティを喜んで使用します。

入力例:

<rss version="2.0">
  <channel>
    <title>Malicious IPs | By Last Bad Event | Project Honey Pot</title>
    <link><![CDATA[http://www.projecthoneypot.org/list_of_ips.php]]></link>
    <description/>
    <copyright>Copyright 2021 Unspam Technologies, Inc</copyright>
    <language>en-us</language>
    <lastBuildDate>July 03 2021 07:15:12 PM</lastBuildDate>
    <image>
      <url>http://www.projecthoneypot.org/images/small_phpot_logo.jpg</url>
      <title>Project Honey Pot | Distribute Spammer Tracking System</title>
      <link>http://www.projecthoneypot.org</link>
    </image>
    <item>
      <title>92.204.241.167 | C</title>
      <link>http://www.projecthoneypot.org/ip_92.204.241.167</link>
      <description>Event: Bad Event | Total: 3,061 | First: 2021-03-27 |  Last: 2021-07-03</description>
      <pubDate>July 03 2021 07:15:12 PM</pubDate>
    </item>
    <item>
      <title>181.24.239.244</title>
      <link>http://www.projecthoneypot.org/ip_181.24.239.244</link>
      <description>Event: Bad Event | Total: 1 | First: 2021-07-03 |  Last: 2021-07-03</description>
      <pubDate>July 03 2021 07:15:12 PM</pubDate>
    </item>
    <item>
      <title>193.243.195.66 | S</title>
      <link>http://www.projecthoneypot.org/ip_193.243.195.66</link>
      <description>Event: Bad Event | Total: 4 | First: 2021-06-12 |  Last: 2021-07-03</description>
      <pubDate>July 03 2021 07:15:12 PM</pubDate>
    </item>
  </channel>
</rss>

希望の出力:

92.204.241.167
181.24.239.244
193.243.195.66

現在の出力:

92.204.241.167

答え1

使用xmlstarlet:

xmlstarlet sel -t -m '//item/link' -v 'substring-after(., "_")' -nl rss.xml

これは最初に-mすべての//item/linkノードと一致()し、次に一致-vしたノード値()から最初のアンダースコア文字の後に続く文字列に関連付けられた値を取得します。最後に、-nl各結果文字列の間に改行文字を出力します。

substring-after()2番目の式()は、最初の式と一致するコレクション内の各ノードに対して評価されます。

答え2

実際、XPath 1.0だけでは不可能です。 XPath 1.0にはそのようなデータ型がないため、一連の文字列を返すことはできず、中間結果として一連の部分文字列がまだ必要であり、再び、そのような種類がないため、個々の部分文字列を連結する単一の文字列を返すことはできません。データ。そのため、XPath 2.0以降に移行する必要があるか、複数のXPath表現を実行するホスト言語の助けが必要です。これは @Kusalananda の xmlstarlet ソリューションが行うことです。

ただし、コマンドラインを使用するため、選択できるツールは非常に多様です。 XPathを使用するのと同じくらい簡単にXQueryを使用でき、確かに古代のXPath 1.0バージョンに限定されません。たとえば、Saxonの場合、次のことができます。

java net.sf.saxon.Query -qs:"//item/link!substring-after(., '_')" -s:rss.xml

これは、XPath 3.0およびXQuery 3.0で利用可能な「バン」演算子を使用します。この演算子は、左式で選択された各項目に右式を適用します。

答え3

私のものヒデル最新のXPath式を実行するための別のツールです。

xidel rss.xml --xpath "//item/link/substring-after(., '_')"

関連情報