Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:从XML文件中提取HTML_Python_Html_Xml_Lxml - Fatal编程技术网

Python:从XML文件中提取HTML

Python:从XML文件中提取HTML,python,html,xml,lxml,Python,Html,Xml,Lxml,我的XML文件如下所示: <strings> <string>Bla <b>One &amp; Two</b> Foo</string> </strings> blaone&;二福 我想在保留内部标签的同时提取每个标签的内容。也就是说,我希望看到以下Python字符串:u“blaone&twoo”。或者,我想我可以选择u“Bla One&Two Foo”,然后尝试自己替换实体 我目前正在使

我的XML文件如下所示:

 <strings>
      <string>Bla <b>One &amp; Two</b> Foo</string>
 </strings>

blaone&;二福
我想在保留内部标签的同时提取每个标签的内容。也就是说,我希望看到以下Python字符串:u“blaone&twoo”。或者,我想我可以选择u“Bla One&Two Foo”,然后尝试自己替换实体

我目前正在使用lxml,它允许我迭代嵌套的标记,忽略标记中没有的文本,或者覆盖所有文本内容(itertext),丢失标记信息。我可能错过了什么

如果可能的话,我更愿意保留lxml,不过如果需要,我可以切换到另一个库。

试试看

outer=etree.tostring(string\u elem,method='html')
inner=re.match(“^[^>]+>(.*)try

outer=etree.tostring(string\u elem,method='html')

inner=re.match(“^[^>]+>(.*)不管使用哪种语言,相对简单的XSLT模板都可以做到这一点

类似于为要保留的标记定义模式,将其转换为其他文本

当然,您可以使用带有兼容DOM实现(可能是minidom?)的递归函数和手动处理标记

(伪代码)

def功能(标签):
if tag.NodeType=“#text”:返回tag.innerText
text=“”
如果allowedTags中的tag.ElementName:
text=”“%tag.ElementName
text+=[tag.childs中子标签的函数(子标签)]
如果allowedTags中的tag.ElementName:
text+=“”%tag.ElementName
返回文本

无论使用哪种语言,相对简单的XSLT模板都可以做到这一点

类似于为要保留的标记定义模式,将其转换为其他文本

当然,您可以使用带有兼容DOM实现(可能是minidom?)的递归函数和手动处理标记

(伪代码)

def功能(标签):
if tag.NodeType=“#text”:返回tag.innerText
text=“”
如果allowedTags中的tag.ElementName:
text=”“%tag.ElementName
text+=[tag.childs中子标签的函数(子标签)]
如果allowedTags中的tag.ElementName:
text+=“”%tag.ElementName
返回文本

不使用解析器,只使用纯字符串操作

mystring="""
 <strings>
      <string>Bla <b>One &amp; Two</b> Foo</string>
 </strings>
"""
for s in mystring.split("</string>"):
    if "<string>" in s:
        i = s.index("<string>")
        print s[i+len("<string>"):].replace("&amp;","")
mystring=”“”
布拉一二福
"""
对于mystring.split(“”)中的s:
如果s中有“”:
i=标准指数(“”)
打印s[i+len(“”):。替换(“&;”,“”)

不使用解析器,只使用纯字符串操作

mystring="""
 <strings>
      <string>Bla <b>One &amp; Two</b> Foo</string>
 </strings>
"""
for s in mystring.split("</string>"):
    if "<string>" in s:
        i = s.index("<string>")
        print s[i+len("<string>"):].replace("&amp;","")
mystring=”“”
布拉一二福
"""
对于mystring.split(“”)中的s:
如果s中有“”:
i=标准指数(“”)
打印s[i+len(“”):。替换(“&;”,“”)

可能有更好的方法可以有条件地处理
xpath()
函数返回的对象,但我对
lxml
不够熟悉,不知道它是什么,所以我必须编写一个函数来返回节点的文本值。不过,这说明了解决问题的一般方法:

>>> from lxml import etree
>>> from StringIO import StringIO
>>> def node_text(n):
        try:
            return etree.tostring(n, method='html', with_tail=False)
        except TypeError:
            return str(n)

>>> f = StringIO('<strings><string>This is <b>not</b> how I plan to escape.</string></strings>')
>>> x = etree.parse(f)
>>> ''.join(node_text(n) for n in x.xpath('/strings/string/node()'))
'This is <b>not</b> how I plan to escape.'
来自lxml导入etree的
>>
>>>从StringIO导入StringIO
>>>def节点_文本(n):
尝试:
返回etree.tostring(n,method='html',带有\u tail=False)
除类型错误外:
返回str(n)
>>>f=StringIO('这不是我计划逃跑的方式')
>>>x=etree.parse(f)
>>>'.join(x.xpath('/strings/string/node()')中n的node_text(n)
“这不是我打算逃跑的方式。”

可能有更好的方法可以有条件地处理
xpath()
函数返回的对象,但我对
lxml
不够熟悉,不知道它是什么,所以我必须编写一个函数来返回节点的文本值。不过,这说明了解决问题的一般方法:

>>> from lxml import etree
>>> from StringIO import StringIO
>>> def node_text(n):
        try:
            return etree.tostring(n, method='html', with_tail=False)
        except TypeError:
            return str(n)

>>> f = StringIO('<strings><string>This is <b>not</b> how I plan to escape.</string></strings>')
>>> x = etree.parse(f)
>>> ''.join(node_text(n) for n in x.xpath('/strings/string/node()'))
'This is <b>not</b> how I plan to escape.'
来自lxml导入etree的
>>
>>>从StringIO导入StringIO
>>>def节点_文本(n):
尝试:
返回etree.tostring(n,method='html',带有\u tail=False)
除类型错误外:
返回str(n)
>>>f=StringIO('这不是我计划逃跑的方式')
>>>x=etree.parse(f)
>>>'.join(x.xpath('/strings/string/node()')中n的node_text(n)
“这不是我打算逃跑的方式。”

实际上我知道使用字符串,但这包括字符串标记本身。手动删除并不难,一个简单的正则表达式可以+1找到一种罕见的情况,在这种情况下,使用正则表达式处理XML并不是一个糟糕、糟糕的主意。谢谢大家。我想去掉周围的标记也会很好。我实际上,我知道tostring,但这包括字符串标记本身。手动删除并不难,一个简单的正则表达式可以+1找到一种罕见的情况,在这种情况下,使用正则表达式处理XML并不是一个糟糕、糟糕的主意。谢谢各位。我想去掉周围的标记也可以。以下列表这种方法的错误之处并不短:除其他外,如果有空的
元素,或者任何
元素包含属性,或者在其开始或结束标记中包含空格,或者任何文本节点包含字符实体或CDATA,则该方法将失败。您假设的内容太多!!。这是一个坏习惯。此列表错误使用这种方法并不短:除其他外,如果存在空的
元素,或者任何
元素包含属性,或者在其开始或结束标记中包含空格,或者任何文本节点包含字符实体或CDATA,则该方法将失败。您假设的内容太多!!。这是一个坏习惯。结果是,不使用node(),您也可以child.iterDescents(),但感谢您为我指明了正确的方向。事实证明,您也可以child.iterDescents(),而不是使用node(),但感谢您为我指明了正确的方向。