web-dev-qa-db-ja.com

XMLファイルから単一の属性を抽出するにはどうすればよいですか?

私は正規表現やsedなどにあまり精通しておらず、この時点でそれを理解するのが少し面倒なので、この行をどのように抽出しますか。

<yweather:astronomy sunrise="6:50 am" sunset="7:06 pm"/>

さらにxml構造が必要かどうかを教えてください。

2
knl

入力データ(XMLファイル)は構造化されているため、プレーンテキストとして処理し、正規表現をいじるのではなく、その構造化データに対してクエリを使用する方が適切です。

xmllint --xpathを使用して、xml入力のXPath式を評価できます。

$ xmllint --xpath 'string(rss/channel/*[local-name()="astronomy"]/@sunrise)' weather.xml
6:48 am

-このファイル内の異なる名前空間を処理する必要があるため、これは少し複雑ですが、それでも動作します。

XPathの詳細については、仕様は http://www.w3.org/TR/xpath/ にあります。

5
Jeremy Kerr

正規表現またはsedは使用しません。 XMLパーサーとXMLクエリ言語(XPathまたはXQuery)を使用します。また、詳細はコンテキストに依存するのではないかと心配しています。たとえば、「yweather」は名前空間の短い名前(プレフィックス)であり、それが表す名前空間を知る必要があります。

3
Michael Kay

Michael Kayが言うように、正しい答えはXML固有のツールを使用することです。

迅速で汚い解決策のために、sedアプローチがあります。このファイルから始めましょう:

$ cat file
<yweather:astronomy sunrise="6:50 am" sunset="7:06 pm"/>

日没時間を抽出するには:

$ sed -rn 's/.*sunset="([^"]*)".*/\1/p' file
7:06 pm

正規表現を理解するために、3つの部分に分けましょう。

  1. .*は、行の先頭から2番目の部分まで一致します

  2. この部分sunset="([^"]*)"は、sunset="の後に"を除く任意の数の文字が続き、最後に"が続く文字に一致します。式[^"]は、"を除く任意の文字を意味し、[^"]*はそのような文字の任意の数を意味します。括弧((...))は、"..."内の文字を、後で\1として参照するsedのグループ1に取り込みます。

  3. .*は、日没表現の後のすべての文字に一致します。

2
John1024

Jeremy Kerr と同じ答えをしますが、例ではxmlを付けます。

アウトルートフォルダーにconfig.xmlというxmlファイルがあり、タグの属性またはプロパティを読み取りたい場合、それをwidgetタグとします。

config.xml

<?xml version='1.0' encoding='utf-8'?>
<widget Android-versionCode="16" id="co.app.world" ios-CFBundleVersion="0.1.3" version="3.0.5" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.Apache.org/ns/1.0">
    <name>AppName</name>
    <description>Description.</description>
    <author email="hi@ionicframework" href="http://ionicframework.com/">Ionic Framework Team</author>
</widget>

Android-versionCodeプロパティ値を取得したいので、ターミナルにこれを入力します:

xmllint --xpath "string(//*[local-name()='widget']/@Android-versionCode)" config.xml

出力:

16

説明:/*[local-name()='widget']を使用してwidgetタグをマップし、@Android-versionCodeを使用してこのプロパティを読み取ります。

0
Luigi Lopez