Python解析XML-if元素==";“价值”;多克斯

Python解析XML-if元素==";“价值”;多克斯,python,xml,Python,Xml,抱歉,如果标题不太清楚,我当前正在解析一个包含许多嵌套标记的xml文件,例如: <Artifacts> <Artifact name="1"> <Fragments> <hits> <hit sequence="1"> <Fragment name="1">Data</Fragment> <Fragment name="2">Data</Fragment&

抱歉,如果标题不太清楚,我当前正在解析一个包含许多嵌套标记的xml文件,例如:

<Artifacts>
 <Artifact name="1">
  <Fragments>
   <hits>
    <hit sequence="1">
     <Fragment name="1">Data</Fragment>
     <Fragment name="2">Data</Fragment>
    </hit>
   </hits>
  </Fragments>
 </Artifact>
 <Artifact name="2">

数据
数据
(让布局更清晰一点对不起) 等等我现在的痛苦是只能得到我们需要的数据。从上面的示例中,我们需要工件名称=1下的所有内容,并将片段名称“1”与数据一起取出。其目标是:

Artifact=“1”,Fragment Name=“1”,Fragment Data=“Data”

目前,我似乎无法掌握它,我已经用PHP做了类似的工作,没有任何问题,但这确实需要用python来完成

抱歉,有点啰嗦,但是有没有人知道如何指定只从名为1,3,5的工件中获取数据,而忽略其他所有内容?我所能做的似乎就是从文件中的所有内容中获取它(这会减慢速度,然后需要进一步处理)

谢谢。

使用minidom:

from xml.dom import minidom

xmlstr = '''
<Artifacts>
<Artifact name="1">
<Fragments>
<Fragment name="1">Data</Fragment>
</Fragments>
</Artifact>
<Artifact name="2">
</Artifact>
</Artifacts>
'''


def with_children(tag):
    if tag.localName: # if not, it's text node
        print tag.localName,
        if tag.hasAttributes():
            for item in tag.attributes.items():
                print "%s=%s" % item,

        for child in tag.childNodes:
            with_children(child)

    else:
        s = tag.nodeValue.strip()
        print "data=%s" % s if s else "",

xml = minidom.parseString(xmlstr)
tags = xml.getElementsByTagName('Artifact')
tag = [t for t in tags if t.attributes['name'].value == '1'][0]
with_children(tag)
从xml.dom导入minidom
xmlstr=''
数据
'''
带_子项的def(标签):
if tag.localName:#如果不是,则为文本节点
打印tag.localName,
如果标记.hasAttributes():
对于tag.attributes.items()中的项:
打印“%s=%s”项,
对于tag.childNodes中的子节点:
有子女(子女)
其他:
s=tag.nodeValue.strip()
打印“数据=%s”%s,如果是“”,
xml=minidom.parseString(xmlstr)
tags=xml.getElementsByTagName('Artifact'))
如果t.attributes['name'],则标记=[t表示标记中的t。值=='1'][0]
带_子对象(标签)

下面是一个使用
lxml
的简单示例:

from lxml import etree

content = '''\
<Artifacts>
  <Artifact name="1">
    <Fragments>
      <Fragment name="1">Data</Fragment>
    </Fragments>
  </Artifact>
  <Artifact name="2">
    <Fragments>
      <Fragment name="2">Data2</Fragment>
    </Fragments>
  </Artifact>
  <Artifact name="3">
    <Fragments>
      <Fragment name="3">Data3</Fragment>
    </Fragments>
  </Artifact>
</Artifacts>
'''

tree = etree.XML(content)

elts = tree.xpath("/Artifacts/Artifact[@name = '1' or @name = '3' or @name = '5']")

for elt in elts:
    etree.dump(elt)
您将获得:

<Artifact name="1">
    <Fragments>
      <Fragment name="1">Data</Fragment>
    </Fragments>
  </Artifact>

<Artifact name="3">
    <Fragments>
      <Fragment name="3">Data3</Fragment>
    </Fragments>
  </Artifact>
Artifact = "1", Fragment Name = "1", Fragment Data = "Data".
Artifact = "3", Fragment Name = "3", Fragment Data = "Data3".

你听说过XPath吗?安装[lxml](并搜索与
“/Artifacts/Artifact[@name='1'或@name='3'或@name='5']”匹配的元素)
,例如@LaurentPorte或
[@name=('1','3','5')]
;在XPath中,
=
实际上是在寻找集合交集。@Charles Duffy:XPath的哪个版本?我从来没有听说过,这一定是最近的变化。但是
lxml
不喜欢它:
tree.XPath(/Artifacts/Artifact[@name=('1','3','5'))
raises
lxml.etree.xpathevaleror:Invalid expression
.Argh。我对XPath的介绍不太清楚,因为XPath是XQuery的一个子集(我对XQuery的熟悉程度主要是3.0)。这非常感谢:)我以前使用过minidom,所以这更符合我的习惯(一点)并且一直在尝试。将尝试并调整这一点以满足我的更多需求,因为最终结果是更改XML文件的格式以允许导入到另一个系统中。是否有一种方法可以进行搜索,然后保持XML格式能够循环通过它来获取所需的数据?只获取“数据”,因为这将在以后需要是否可以更改为类似“数据”等的xml格式?有minidom.getDom实现来创建文档和节点。
Artifact = "1", Fragment Name = "1", Fragment Data = "Data".
Artifact = "3", Fragment Name = "3", Fragment Data = "Data3".