【问题标题】:In Python, Parsing Custom XML Tags Without Parsing HTML在 Python 中,解析自定义 XML 标签而不解析 HTML
【发布时间】:2015-07-19 03:55:10
【问题描述】:

我是 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>')

原始代码将只返回以第一个 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'

【问题讨论】:

  • 解析自定义 XML 标签而不解析任何 HTML 内容是什么意思
  • XML 文件与 HTML 文件类似,不同之处在于您可以定义自己的标签。我认为实现这一点的唯一可能方法是为要忽略或解析的标签添加几个 if-else 条件。不要以为python中有任何预构建的库可以忽略HTML标签。
  • @AnandSKumar,我希望能够访问位于我想要解析的 XML 标记内的未解析 HTML。我更新了我的帖子,试图更清楚地说明这一点。
  • @user2197148 我猜你弄错了,即使你的文件没有被 html 解析,&lt;p&gt; 仍然是一个有效的 xml 标签,它会被视为一个 xml 元素。

标签: python xml parsing elementtree xml.etree


【解决方案1】:

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

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>

【讨论】:

  • 这行得通,但谈论“未解析的内容”似乎很奇怪。 fromstring() 解析一切; XML 中没有“未解析”的部分。
  • 我明白你的意思,我只是想从 OP 的角度解释(我个人称之为 inner XMLinner HTML,受属性名称的影响,以便在 .NET 中获得相同XML/HTML 解析器)
【解决方案2】:

您应该可以通过内置的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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-24
    • 2016-02-12
    • 1970-01-01
    • 2015-02-14
    • 1970-01-01
    相关资源
    最近更新 更多