4

私はpython 2.7を使用しており、以下のXMLを解析しようとしています - 私がやろうとしているのは、言語属性を持つすべてのジャンルのpython配列と、言語属性のない配列を作成することです。

私はpythonモジュールを使用していますimport xml.etree.cElementTree as ET

言語属性が「fr」言語の XML セクションを構文で見つけることができることはわかっています。

tree=ET.ElementTree(file='popups.xml')
ルート = tree.getroot()
for x in root.findall('alt[@{http://www.w3.org/XML/1998/namespace}lang="fr"]/alt'):
   x.text を印刷

xml:langではなくを使用できない理由がよくわかりません{http://www.w3.org/XML/1998/namespace}langが、上記は Ubuntu 12.04 で動作するようです

私が見つけようとしているのは、「not」構文です-XMLセクションには言語属性がありません

これを達成する方法を考えている人はいますか?

<genre>
  <alt>
        <alt genre="easy listening">lounge</alt>
        <alt genre="alternative">ska</alt>
  </alt>

  <alt xml:lang="fr">
        <alt genre="gospel">catholique</alt>
  </alt>
</genre>
4

2 に答える 2

4

stdlib ElementTree にはプレフィックスを登録する方法がないため、xpath で完全な QName を使用する必要があります。通常、ヘルパー関数を使用して QName を作成します。

def qname(prefix, element, map={'xml':'http://www.w3.org/XML/1998/namespace'}):
    return "{{{}}}{}".format(map[prefix], element)

標準ライブラリのElementTree実装は、必要なことを簡単に行うのに十分な XPath をサポートしていません。ただし、仕様でxml:langxml:baseは、この属性の値が、それを含むすべてのもの (likeまたはxmlns名前空間宣言のようなもの) に継承されることを指定しています。別の方法として、すべての要素で言語設定を明示的にすることができます。

xml_lang = qname('xml', 'lang')

def set_xml_lang(root, defaultlang=''):
    xml_lang = qname('xml', 'lang')
    for item in root:
        try:
            lang = item.attrib[xml_lang]
        except KeyError, err:
            item.set(xml_lang, defaultlang)
            lang = defaultlang
        set_xml_lang(item, lang)

set_xml_lang(root)

namespaces = {'xml':'http://www.w3.org/XML/1998/namespace'}
# Every element in root now has an xml:lang attribute
# so XPath is easy now:
alts_with_no_lang = root.findall('alt[@{{{xml}}}lang=""]'.format(**namespaces))

を使用する意思がある場合lxml、「lang」は完全な XPath 1.0 仕様に準拠しているため、より堅牢に使用できます。lang()特に、次の関数を使用できます。

import lxml.etree as ET

root = ET.fromstring(xml)

print root.xpath('//alt[lang("fr")]')

おまけとして、lang()大文字と小文字を区別せず、言語地域についてスマートであるように、適切なセマンティクスがあります (たとえば、言語地域lang('en')にも当てはまりxml:lang="en-US"ます)。

lang()残念ながら、 を使用してノードの言語を判別することはできません。xml:lang最初の祖先を見つけて、それを使用する必要があります。

mylang = node.xpath('(ancestor-or-self::*/@xml:lang)[1]')

すべてをまとめると、言語を持たないノードに一致するようになります。

tree.xpath('//alt[not((ancestor-or-self::*/@xml:lang)[1])]')
于 2013-01-09T23:02:55.473 に答える
1

{http://www.w3.org/XML/1998/namespace}langではなくxml:langを使用できない理由がよくわかりませんが、上記はUbuntu 12.04で動作するようです

あなたがやろうとしていることは、ドキュメントのルート要素から名前空間ラベルを読み取るxpathメソッド (これはでは利用できませcElementTree) を使用することでより簡単になるため、次のように尋ねることができます。

import lxml.etree as et

root = et.parse(open('mydoc.xml')).getroot()

for x in root.xpath('alt[not(@xml:lang)]/alt'):
    print x.text

以前はよく知らなかったnot(@attr)構文ですが、「属性のない xpath 検索要素」の Google 検索は非常に役に立ちました。

于 2013-01-09T22:44:42.150 に答える