Как отфильтровать значения из файла XML в Python - PullRequest
1 голос
/ 18 февраля 2010

У меня есть базовые знания XML и python, и я использую minidom с некоторым успехом Я столкнулся с ситуацией, когда я не могу получить нужные значения из файла XML. Вот базовая структура уже существующего файла.

<localization>
    <b n="Stats">
        <l k="SomeStat1">
            <v>10</v>
        </l>
        <l k="SomeStat2">
            <v>6</v>
        </l>
    </b>
    <b n="Levels">
        <l k="Level1">
            <v>Beginner Level</v>
        </l>
        <l k="Level2">
            <v>Intermediate Level</v>
        </l>
    </b>
</localization>

Существует около 15 различных <b> тегов с десятками детей. Что бы я хотел сделать, если получить номер уровня (1), это найти узел <v> для соответствующего уровня. Я просто понятия не имею, как это сделать.

Ответы [ 5 ]

4 голосов
/ 18 февраля 2010

Возможно, вы решите использовать XPATH, язык для адресации частей XML-документа.

Вот ответ, используя lxml.etree, и он поддерживает xpath.

>>> data = """
... <localization>
...     <b n="Stats">
...         <l k="SomeStat1">
...             <v>10</v>
...         </l>
...         <l k="SomeStat2">
...             <v>6</v>
...         </l>
...     </b>
...     <b n="Levels">
...         <l k="Level1">
...             <v>Beginner Level</v>
...         </l>
...         <l k="Level2">
...             <v>Intermediate Level</v>
...         </l>
...     </b>
... </localization>
... """
>>>
>>> from lxml import etree
>>>
>>> xmldata = etree.XML(data)
>>> xmldata.xpath('/localization/b[@n="Levels"]/l[@k=$level]/v/text()',level='Level1')
['Beginner Level']
2 голосов
/ 18 февраля 2010
#!/usr/bin/python

from xml.dom.minidom import parseString

xml = parseString("""<localization>
    <b n="Stats">
        <l k="SomeStat1">
            <v>10</v>
        </l>
        <l k="SomeStat2">
            <v>6</v>
        </l>
    </b>
    <b n="Levels">
        <l k="Level1">
            <v>Beginner Level</v>
        </l>
        <l k="Level2">
            <v>Intermediate Level</v>
        </l>
    </b>
</localization>""")

level = 1
blist = xml.getElementsByTagName('b')
for b in blist:
    if b.getAttribute('n') == 'Levels':
        llist = b.getElementsByTagName('l')
        l = llist.item(level)
        v = l.getElementsByTagName('v')
        print v.item(0).firstChild.nodeValue;
        #prints Intermediate Level
1 голос
/ 18 февраля 2010

Если бы вы могли использовать библиотеку BeautifulSoup (не так ли?), Вы могли бы получить в итоге такой простой код:

from BeautifulSoup import BeautifulStoneSoup

def get_it(xml, level_n):
    soup = BeautifulStoneSoup(xml)
    l = soup.find('l', k="Level%d" % level_n)
    return l.v.string

if __name__ == '__main__':
    print get_it(1)

Он печатает Beginner Level для примераXML вы указали.

1 голос
/ 18 февраля 2010

Если вы действительно заботитесь только о поиске тега <l> с определенным атрибутом "k" и получении его тега <v> (вот как я понял ваш вопрос), вы можете сделать это с DOM:

from xml.dom.minidom import parseString

xmlDoc = parseString("""<document goes here>""")
lNodesWithLevel2 = [lNode for lNode in xmlDoc.getElementsByTagName("l")
                    if lNode.getAttribute("k") == "Level2"]

matchingVNodes = map(lambda lNode: lNode.getElementsByTagName("v"), lNodesWithLevel2)

print map(lambda vNode: vNode.firstChild.nodeValue, matchingVNodes)
# Prints [u'Intermediate Level']

Как это то, что вы имели в виду.

0 голосов
/ 18 февраля 2010
level = "Level"+raw_input("Enter level number: ")
content= open("xmlfile").read()
data= content.split("</localization>")
for item in data:
    if "localization" in item:
        s = item.split("</b>")
        for i in s:
           if """<b n="Levels">""" in i:
                for c in i.split("</l>"):
                    if "<l" in c and level in c:
                         for v in c.split("</v>"):
                            if "<v>" in v:
                                print v[v.index("<v>")+3:]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...