3

Python を使用して非常に単純な XML を解析しようとしています。

Python 3 より前は、XPath 機能を備えた「webscraping」ライブラリを使用していました。非常に簡単に動作します:

xpath.search(xml (xml string), "XPath Query (//search)"

- 提供された XPath クエリに基づいて、見つかった要素を返します。

今、私は Python 3 に切り替えることにしましたが、上記のライブラリは (2to3.py の後でも) Python 3 で適切に動作しないため、ネイティブxml.etree.ElementTreeライブラリを使用することにしました。

何かわからないかもしれませんが、これは悪夢です。XML および XPath クエリを関数に単純に提供し、結果を返すという方法では機能しません。代わりに、10行以上のコードを使用する必要があり、要素の子などをいじる必要がありますが、それでも機能しません...

import xml.etree.ElementTree as ET
doc = ET.fromstring(xml)
result = doc.findall("//XPath Query")

SyntaxError: cannot use absolute path on element 追加.//XPath Queryてもあまり役に立ちません。

ElementTreeライブラリが非常に複雑で、要素をいじったり、毎回ループlxmlを使用したりする代わりに、単純に XPATH を使用できない理由は何ですか?for

XPathクエリを使用して結果を返すだけのPython 3用のシンプルなライブラリをお勧めできますか?

4

2 に答える 2

2

今問題を見つけました。

XML 応答には次のものが含まれます。

<?xml version="1.0" encoding="utf-8"?>
<GetOrdersResponse xmlns="urn:ebay:apis:eBLBaseComponents">
  <!-- Call-specific Output Fields -->
  <HasMoreOrders> boolean </HasMoreOrders>
  <OrderArray> OrderArrayType
    <Order> OrderType
      <AdjustmentAmount currencyID="CurrencyCodeType"> AmountType (double) </AdjustmentAmount>
      <AmountPaid currencyID="CurrencyCodeType"> AmountType (double) </AmountPaid>
      <AmountSaved currencyID="CurrencyCodeType"> AmountType (double) </AmountSaved>
      <BuyerCheckoutMessage> string </BuyerCheckoutMessage>
      <BuyerUserID> UserIDType (string) </BuyerUserID>
      <CheckoutStatus> CheckoutStatusType
      ...

その XML を解析した後:

root = ET.fromstring(xml)
result = tree.findall("*")

プレフィックス付きのすべての単一要素を返します{urn:ebay:apis:eBLBaseComponents}

たとえば、検索する必要がある場合<BuyerCheckoutMessage>

result = tree.findall(".//BuyerCheckoutMessage")その要素は のように見えるため、何も返されません{urn:ebay:apis:eBLBaseComponents}BuyerCheckoutMessage

したがって、要素を検索する{urn:ebay:apis:eBLBaseComponents}には、要素を取得するためにすべての XPath クエリの前に含める必要があります。

したがって、解決策は使用することです:

result = tree.findall(".//{urn:ebay:apis:eBLBaseComponents}BuyerCheckoutMessage") result[0].text要素の値を返します。

ET.search(xml, "XPath-query") のように機能しない理由は、私にとって最大の秘密です。とても多くの時間を無駄にしました。

于 2013-04-03T18:58:11.240 に答える
2

http://docs.python.org/2/library/xml.etree.elementtree.htmlのサンプル xml を使用すると、検索はうまくいくようです。

>>> import xml.etree.ElementTree as ET
>>> xml = """..."""
>>> doc = ET.fromstring(xml)
>>> doc.findall(".//rank")
[<Element 'rank' at 0x10199ebd0>, <Element 'rank' at 0x10199e210>, <Element 'rank' at 0x10199e4d0>]

または、ルートから明示的に検索する場合:

>>> ET.ElementTree(doc).findall('//rank')
于 2013-04-03T14:37:20.090 に答える