在 Python 中,解析自定义 XML 标记而不解析 HTML

In Python, Parsing Custom XML Tags Without Parsing HTML

我是 Python 2.7 的新手,我正在尝试解析包含 HTML 的 XML 文件。我想解析自定义 XML 标签 ,而不解析任何 HTML 内容 。最好的方法是什么? (如果有帮助的话,我的自定义 XML 标签列表很小,所以如果有一个 XML 解析器可以选择只解析指定的标签,这可能会很好。)

例如我有一个 XML 文件,看起来像

<myTag1 myAttrib="value">
  <myTag2>
    <p>My what a lovely day.</p>
  </myTag2>
</myTag1>

我希望能够解析除 HTML 之外的所有内容,特别是将 myTag2 的值提取为未解析的 HTML.

编辑:这里有更多信息来回答下面的问题。我以前曾尝试使用 ElementTree。事情是这样的:

root = ET.fromstring(xmlstring)
root.tag  # returns 'myTag1'
root[0].tag  # returns 'myTag2'
root[0].text  # returns None, but I want it to return the HTML string

我要的HTML字符串已经解析并存储为标签和文本:

root[0][0].tag  # returns 'p', but I don't even want root[0][0] to exist
root[0][0].text  # returns 'My ... day.'

但我真的很想做这样的事情...

root[0].unparsedtext  # returns '<p>My ... day.</p>'

解决方案:

har07 的回答很有效。我稍微修改了该代码以解决边缘情况。这是我正在实施的:

def _getInner(element):
    if element.text == None:
        textStr = ''
    else:
        textStr = element.text
    return textStr + ''.join(ET.tostring(e) for e in element)

那么如果

element = ET.fromstring('<myTag>Let us be <b>gratuitous</b> with tags</myTag>')

原始代码只会 return 以第一个 XML 格式的标签开头的文本,但修改后的版本将捕获所需的文本:

''.join(ET.tostring(e) for e in element)  # returns '<b>gratuitous</b> with tags'

_getInner(element)  # returns 'Let us be <b>gratuitous</b> with tags'

您应该能够通过内置的 minidom xml 解析器实现它。

from xml.dom import minidom

xmldoc = minidom.parse("document.xml")
rootNode = xmldoc.firstChild
firstNode = rootNode.childNodes[0]

在您的示例中,firstNode 最终会是:

<p>My what a lovely day.</p>

请注意,默认情况下 minidom(可能还​​有您可能使用的任何其他 xml-解析库)不会识别 HTML。这是设计使然,因为 XML 文档没有预定义标签。

然后您可以使用一系列 iftry 语句来确定您在提取数据时是否到达了 HTML 格式的节点:

for i in range (0, len(rootNode))
    rowNode = rootNode.childNodes[i]
    if "<p>" in rowNode:
         #this is an html-formatted node: extract the value and continue

我认为没有一种简单的方法可以修改 XML 解析器行为以忽略一些预定义的标签。一种更简单的方法是让解析器正常解析 XML,然后您可以创建一个 return 未解析元素内容的函数,例如:

import xml.etree.ElementTree as ET

def getUnparsedContent(element):
    return ''.join(ET.tostring(e) for e in element)

xmlstring = """<myTag1 myAttrib="value">
  <myTag2>
    <p>My what a lovely day.</p>
  </myTag2>
</myTag1>"""

root = ET.fromstring(xmlstring)
print(getUnparsedContent(root[0]))

输出:

<p>My what a lovely day.</p>