0

假设我有一个示例配置 XML 文件,如下所示:

<?xml version="1.0"?>
<note> 
    <to>Tove</to> 
    <infoaboutauthor>
      <nestedprofile>
           <aboutme> 
               <gco:CharacterString>I am a 10th grader who likes to play ball.</gco:CharacterString> 
          </aboutme>
      </nestedprofile>
    </infoaboutauthor>
    <date>
        <info_date>
            <date>
               <gco:Date>2003-06-13</gco:Date>
            </date>
            <datetype>
                <datetype attribute="Value">
                </datetype>
            </datetype>
        </info_date>
    </date>
    <from>Jani</from> 
    <heading>Reminder</heading> 
    <body>Don't forget me this weekend!</body> 
  </note>

在 python 中(尝试使用 ElementTree,不确定它是否是最好的)我想为某些标签获取某些值。我试过了:

with open('testfile.xml', 'rt') as f:
    tree = ElementTree.parse(f)
print 'Parsing'
root = tree.getroot()
listofelements = root_elem.findall('gco:CharacterString')    
for elementfound in listofelements:
    print elementfound.text

在我上面使用的代码中,当我有冒号时它似乎不起作用,因为我收到以下错误:

SyntaxError: prefix 'gco' not found in prefix map

我的目标是

  1. 获取“2003-06-13”标签中的文本
  2. “aboutme”标签中的文字

实现这一目标的最佳方法是什么?有没有办法查找父级等于“aboutme”的“gco:CharacterString”?或者有什么方便的方法可以把它变成我可以去的字典mydict['note']['to']['nestedprofile']['aboutme']吗?

注意:“gco:”前缀是我必须处理的,它是 xml 的一部分。如果 elementtree 不适合这个,那没关系。

4

2 回答 2

1

首先,您的 XML 已损坏。第-2 行正在破坏解析器。我也不认为它喜欢gco:s。您可以使用其他一些 XML 配置吗?或者这是由你无法控制的东西自动生成的?

因此,要使其与 Python 一起使用,XML 需要如下所示:

<?xml version="1.0"?>
<note>
    <to>Tove</to>
    <infoaboutauthor>
      <nestedprofile>
           <aboutme>
               <CharacterString>I am a 10th grader who likes to play ball.</CharacterString>
          </aboutme>
      </nestedprofile>
    </infoaboutauthor>
    <date>
        <info_date>
            <date>
               <Date>2003-06-13</Date>
            </date>
            <datetype>
                <datetype attribute="Value">
                </datetype>
            </datetype>
        </info_date>
    </date>
    <from>Jani</from>
    <heading>Reminder</heading>
    <body>Don't forget me this weekend!</body>
  </note>

这是实现您的两个目标的代码:

# Get the element tree from the file name and not a file object
tree = ElementTree.parse('config.xml')

# Get the root of the tree
root = tree.getroot()

# To get the 'Date' tag and print its text
date_tag = root.find('date').find('info_date').find('date').find('Date')
print date_tag.text

# Get the `aboutme` tag and print its text
about_me_tag = root.find('infoaboutauthor').find('nestedprofile').find('aboutme').find('CharacterString')
print about_me_tag.text

更新

就处理“gco:”而言,您可以执行以下操作:

def replace_in_config(old, new):
    with open('config.xml', 'r') as f:
        text = f.read()

    with open('config.xml', 'w') as f:
        f.write(text.replace(old, new))

然后在执行上述 XML 操作之前运行:

replace_in_config('gco:', '_stripped')

然后在 XMl 操作完成后(当然,您需要考虑gco:Date标签现在stripped_Date和 CharacterString 标签一样的事实),运行以下命令:

replace_in_config('_stripped', 'gco:')

这将保留原始格式并允许您使用etree.

于 2012-08-16T14:19:10.220 回答
0

我认为您的 XML 文档无效,因为尚未定义“gco”命名空间。

我找不到将定义提供给 lxml 作为 parse 命令的一部分的方法。您可以按照@mjgpy3 的建议操作文档以添加定义或删除前缀。

另一种方法可能是使用 HTML 解析器,因为它对接受的内容没有那么严格。请注意,这将更改数据结构以添加 HTML 标头等。

from lxml import etree

Parser = etree.HTMLParser()
XMLDoc = etree.parse(open('C:/Temp/Test.xml', 'r'), Parser)

Elements = XMLDoc.xpath('//characterstring')

for Element in Elements:
    print Element.text
于 2012-08-16T16:35:21.200 回答