2

amazon深くネストされた大きなXMLドキュメント(bookstore.xml)のこのスニペットを考えると、ノードへのフルパスを知りたいと思います。コマンドラインからそのパスを印刷するにはどうすればよいですか?

<bookstore>
<book>
  <title lang="eng">Learning XML</title>
  <price>
    <retail>39.95</retail>
    <discounts>
      <amazon>29.99</amazon>
    </discounts>
    <currency>USD</currency>
  </price>
</book>
...
</bookstore>

理想的には、次のようになります。

old-gregg$ magic bookstore.xml amazon
/bookstore/book/price/discounts/amazon
4

3 に答える 3

8

XMLStarletを見つけましたが、ここで探しているものを正確に実行します。Homebrewを使用してインストールするには:

$ brew update
$ brew install xmlstarlet
$ xml el bookstore.xml | grep amazon
/bookstore/book/price/discounts/amazon
于 2012-08-17T21:08:27.300 に答える
5

libxml2にバンドルされているコマンドラインツールであるxmllintを使用します。お使いのシステムで利用できる可能性が非常に高いです。

サンプルデータ(省略記号を削除)に基づいて、私は次のことを試して管理しました。

echo -e "du\nbye\n" | \
  xmllint --shell data

これは

/ > du
/
bookstore
  book
    title
    price
      retail
      discounts
        amazon
      currency
/ > bye

これは、ツールのインタラクティブモードを使用します。
du現在のノード(ここではルート)から始まるサブツリー全体を出力するように依頼します。 byeプログラムを終了するだけです。

次のステップは、この出力を解析することです。

更新: (XMLがにあると仮定してdata
問題のノードは現在ハードコーディングされていることに注意してください!

#!/bin/bash

echo -e "du\nbye\n" | \
  xmllint --shell data | \
  sed 's/  /: /g' | \
  awk '
    BEGIN {depth = 0}
    $NF == "amazon" {
      for(i=1; i<NF; i++) {printf("/%s", STACK[i])}
      print "/" $NF
    }
    /^\// {next}
    NF == depth + 1 {depth = NF; STACK[depth] = $NF; next}
    NF == depth {STACK[depth] = $NF; next}
    NF < depth {depth = NF; STACK[depth] = $NF; next}
    1 {print "something went horribly wrong!"}
  '

与える

/bookstore/book/price/discounts/amazon

これを説明するには、sedコマンド後の出力を見てください。

/ > du
/
bookstore
: book
: : title
: : price
: : : retail
: : : discounts
: : : : amazon
: : : currency
/ > bye

sedに置き換え[two spaces]ます[:space]
以下では、で深さを検出するのは簡単awkです。

于 2012-08-17T20:19:37.873 に答える
0

XPath 2.0では//amazon、要素を選択し/ancestor-or-self::*/node-name(.)て親ノード名string-join(..., "/")を取得し、そこからパスを取得するために使用できます。

最後に、XPath2.0式

string-join(("",//amazon/ancestor-or-self::*/node-name(.)),"/")

希望するパスを正確に返します。([]属性テストは追加されませんが、必要に応じて追加されます)

他にXPath2.0コマンドラインツールがあるかどうかはわかりませんが、数日前に自分で作成しました。fpcを使用している場合は、ソースをダウンロードしてコンパイルできます(バイナリ編集はありません。現在、そこにリンクされています:http: //videlibri.sourceforge.net/xidel.html)。これを使用すると、次のように実行できます。

 xidel /tmp/so2.xml --extract 'string-join(("",//amazon/ancestor-or-self::*/node-name(.)),"/")'

私はあなたが試すことができるCGIサービスも作りました:

  wget -qO - 'http://videlibri.sourceforge.net/cgi-bin/xidelcgi?extract=string-join(("",//amazon/ancestor-or-self::*/node-name(.)),"/")&data=<bookstore><book>  <title lang="eng">Learning XML</title>  <price>   <retail>39.95</retail>    <discounts>      <amazon>29.99</amazon>    </discounts>    <currency>USD</currency>  </price></book></bookstore>'  
于 2012-08-17T21:06:41.323 に答える