Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.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
XML节点的python报告行/原始列_Python_Xml_Dom_Sax - Fatal编程技术网

XML节点的python报告行/原始列

XML节点的python报告行/原始列,python,xml,dom,sax,Python,Xml,Dom,Sax,我目前正在使用xml.dom.minidom在python中解析一些xml。解析之后,我将对内容进行一些报告,并希望报告标记在源XML文档中开始的行(和列),但我不认为这是可能的 如果可能的话,我希望继续使用xml.dom/xml.dom.minidom,但是如果我需要使用SAX解析器来获取源信息,我可以做到这一点——理想的情况是使用SAX跟踪节点位置,但最终还是使用dom进行后期处理 有什么建议吗?希望我只是忽略了文档中的一些内容,这非常简单。通过MonkeyPatch minidom内容处理

我目前正在使用xml.dom.minidom在python中解析一些xml。解析之后,我将对内容进行一些报告,并希望报告标记在源XML文档中开始的行(和列),但我不认为这是可能的

如果可能的话,我希望继续使用xml.dom/xml.dom.minidom,但是如果我需要使用SAX解析器来获取源信息,我可以做到这一点——理想的情况是使用SAX跟踪节点位置,但最终还是使用dom进行后期处理


有什么建议吗?希望我只是忽略了文档中的一些内容,这非常简单。

通过MonkeyPatch minidom内容处理程序,我能够记录每个节点的行数和列数(作为“parse_position”属性)。这有点脏,但我看不到任何“官方认可”的方法:)这是我的测试脚本:

from xml.dom import minidom
import xml.sax

doc = """\
<File>
  <name>Name</name>
  <pos>./</pos>
</File>
"""


def set_content_handler(dom_handler):
    def startElementNS(name, tagName, attrs):
        orig_start_cb(name, tagName, attrs)
        cur_elem = dom_handler.elementStack[-1]
        cur_elem.parse_position = (
            parser._parser.CurrentLineNumber,
            parser._parser.CurrentColumnNumber
        )

    orig_start_cb = dom_handler.startElementNS
    dom_handler.startElementNS = startElementNS
    orig_set_content_handler(dom_handler)

parser = xml.sax.make_parser()
orig_set_content_handler = parser.setContentHandler
parser.setContentHandler = set_content_handler

dom = minidom.parseString(doc, parser)
pos = dom.firstChild.parse_position
print("Parent: '{0}' at {1}:{2}".format(
    dom.firstChild.localName, pos[0], pos[1]))
for child in dom.firstChild.childNodes:
    if child.localName is None:
        continue
    pos = child.parse_position
    print "Child: '{0}' at {1}:{2}".format(child.localName, pos[0], pos[1])

另一种解决问题的方法是在解析文档之前将行号信息修补到文档中。我的想法是:

LINE_DUMMY_ATTR = '_DUMMY_LINE' # Make sure this string is unique!
def parseXml(filename):
  f = file.open(filename, 'r')
  l = 0
  content = list ()
  for line in f:
    l += 1
    content.append(re.sub(r'<(\w+)', r'<\1 ' + LINE_DUMMY_ATTR + '="' + str(l) + '"', line))
  f.close ()

  return minidom.parseString ("".join(content))
很明显,这种方法有它自己的缺点,如果您真的也需要列号,那么在中对其进行修补将更加复杂。此外,如果要提取文本节点或注释,或使用
Node.toXml()
,则必须确保从任何意外匹配中删除行\u DUMMY\u ATTR,如下所示


与aknuds1的答案相比,此解决方案的一个优点是它不需要处理minidom内部结构。

xmlparser
from
xml.parsers.expat
支持行号/列号<代码>lxml.etree支持行号。
LINE_DUMMY_ATTR = '_DUMMY_LINE' # Make sure this string is unique!
def parseXml(filename):
  f = file.open(filename, 'r')
  l = 0
  content = list ()
  for line in f:
    l += 1
    content.append(re.sub(r'<(\w+)', r'<\1 ' + LINE_DUMMY_ATTR + '="' + str(l) + '"', line))
  f.close ()

  return minidom.parseString ("".join(content))
int (element.getAttribute (LINE_DUMMY_ATTR))