在lxml元素中添加行号

问题描述 投票:0回答:1

我试图找到一种方法,将原始XML文本中的行号添加到python的lxml模块的XML树中构建的每个元素。有些东西可以让我从树中获取一个元素,并简单地做一些事情的效果

       line_num = element.xml_line_num

我知道lxml树元素中有一个sourceline属性,但这不可靠。这并不总是正确的。使用python 2.7默认提供的基本ElementTree,默认解析器有一个名为GetInputContext()的方法,我可以通过循环原始XML文本中的行并与从该输入上下文方法获得的文本进行比较来使用它。我很快发现默认解析器中的CurrentLineNumber不可靠。不得不求助于XML源字符串比较。

无论如何,我对我对子模块的子类化以及让事情有效的理解还不够好。成熟且广泛使用的Python模块在使用Python的许多方面时往往非常彻底和广泛,当你开始处理底层基类的c代码实现时,它会让人感到困惑。因此,一些帮助,也许一些示例代码,将非常感激。提前致谢!

让我补充一些说明。我希望代码看起来像这样:

from lxml import etree as ET


xml_tree = ET.fromstringlist(xml_file_lines)

for xml_element in xml_tree.iter():

    line_num = xml_element.xml_line_num

'xml_file_lines'是从文件读入的XML文件行的列表。其中一些是空行。我可以说我正在处理的文件中的XML行是非空白行和不是注释的行确实显示为打开,关闭,自闭或打开/关闭元素。就是说这样:

<tag>text</tag>
<tag1 />
<tag2 id = "yum" />
<tag2 id = "delicious" name = "tasty">text</tag>
<tag3>
     <tag4>hungry</tag4>
<tag3>

这些XML文件中的任何一行都不会有多个打开或关闭XML标记。有任何想法吗?

xml python-2.7 parsing lxml
1个回答
0
投票

好的,所以,我想出来了。如果从XML文件行的字符串列表中将XML数据加载到lxml etree中,则可以使用feed解析器获取lxml etree元素的sourceline属性,以获取每个XML元素所源自的XML文件行。下面的代码演示了我的所作所为:

from lxml import etree as ET

class LineNumberingParser(ET.XMLParser):

      def __init__(self, *args, **kwargs):

          super(self.__class__, self).__init__(*args, **kwargs)

      def feed(self, data):

           line = data.strip() + "\n"
           super(self.__class__, self).feed(line)     

然后你需要做的就是告诉lxml使用你的行解析器:

from lxml import etree as ET

class LineNumberingParser(ET.XMLParser):

      def __init__(self, *args, **kwargs):

          super(self.__class__, self).__init__(*args, **kwargs)

      def feed(self, data):

           line = data.strip() + "\n"
           super(self.__class__, self).feed(line)     

with open(file.xml, "rU") as FILE:
     xml_file_lines = FILE.readlines()

xml_tree = ET.fromstringlist(xml_file_lines, parser=LineNumberingParser()) 

for xml_element in xml_tree.iter():
    print "XML tag " + xml_element.tag + " found on file line " + str(xml_element.sourceline) + "\n" 

甚至可能不需要子类化lxml XMLParser。所有可能需要的是将XML文件的行读作字符串列表并使用etree.fromstringlist()只要在每行的末尾都有换行符,我认为这一切都很好。

© www.soinside.com 2019 - 2024. All rights reserved.