Python 中的 SAX 是否有一个索引告诉我我在 XML 文件中的位置?我怎么会发现呢?
Does SAX in Python have an index that tells me where I am in an XML file? And how would I find that out?
我有一个具体问题和一个一般问题。
假设我正在使用 SAX 来处理下面的 XML,但它实际上有 17MB 并且复杂得多。代码没有错误,但因为它太复杂了,我可能一开始就不应该接近 SAX,我遇到了一个令人沮丧的逻辑错误——它有时会输出一个我不感兴趣的值,有时正确地忽略它。这个逻辑错误是唯一阻止我完成项目的原因。我正在尝试调试代码,但这非常令人沮丧,因为即使我的截断测试 XML 文件也有 42,000 行。
所以我的具体问题是如何查看 XML 文件的哪一行触发了任何给定的 startElement。 startElement 或 ContentHandler 是否有索引或其他东西告诉您它在文件中的位置?
我的一般问题是我怎样才能找到自己做这件事的方法?我可以在 Google 上四处游荡,Stack Overflow 是一个我非常感激的巨大资源,但如果我可以独立调查我正在使用的东西的属性,那会更令人满意。例如,有没有办法,在我的代码中,我可以得到一个列表,列出所有挂在 startElement 或变量或任何东西上的东西,真的。 Len() 告诉我某物有多长,Type() 告诉我它是什么类型。当我不确定我遇到的问题 种类 时,是否还有其他有用的元命令可以求助?
我有点预料到会因为一个问题问两个问题而被骂,但我知道如何提出一般性问题而不会因为太模糊而被骂。
此代码归功于 http://pyxml.sourceforge.net/topics/howto/node12.html。
<collection>
<comic title="Sandman" number='62'>
<writer>Neil Gaiman</writer>
<penciller pages='1-9,18-24'>Glyn Dillon</penciller>
<penciller pages="10-17">Charles Vess</penciller>
</comic>
</collection>
我用下面的代码处理XML:
from xml.sax import saxutils
class FindIssue(saxutils.handler.ContentHandler):
def __init__(self, title, number):
self.search_title, self.search_number = title, number
def startElement(self, name, attrs):
# If it's not a comic element, ignore it
if name != 'comic': return
# Look for the title and number attributes (see text)
title = attrs.get('title', None)
number = attrs.get('number', None)
if (title == self.search_title and number == self.search_number):
print (title, '#' + str(number), 'found')
from xml.sax import make_parser
from xml.sax.handler import feature_namespaces
if __name__ == '__main__':
# Create a parser
parser = make_parser()
# Tell the parser we are not interested in XML namespaces
parser.setFeature(feature_namespaces, 0)
# Create the handler
dh = FindIssue('Sandman', '62')
# Tell the parser to use our handler
parser.setContentHandler(dh)
# Parse the input
parser.parse("test.xml")
这是您的示例的一个版本,它还打印匹配元素的行和列。
import io
from xml.sax import saxutils
from xml.sax import make_parser
from xml.sax.handler import feature_namespaces
class FindIssue(saxutils.handler.ContentHandler):
def __init__(self, title, number):
self.locator = None
self.search_title = title
self.search_number = number
def setDocumentLocator(self, loc):
self.locator = loc
def startElement(self, name, attrs):
if name != "comic":
return
title = attrs.get("title")
number = attrs.get("number")
if title == self.search_title and number == self.search_number:
if self.locator:
print("Line", self.locator.getLineNumber(), "column", self.locator.getColumnNumber())
print(title, "#" + str(number), "found")
# Create a parser
parser = make_parser()
parser.setFeature(feature_namespaces, 0)
issue_finder = FindIssue("Sandman", "62")
parser.setContentHandler(issue_finder)
parser.parse(
io.StringIO(
"""
<collection>
<comic title="Sandman" number='62'>
<writer>Neil Gaiman</writer>
<penciller pages='1-9,18-24'>Glyn Dillon</penciller>
<penciller pages="10-17">Charles Vess</penciller>
</comic>
</collection>
""".strip()
)
)
我有一个具体问题和一个一般问题。
假设我正在使用 SAX 来处理下面的 XML,但它实际上有 17MB 并且复杂得多。代码没有错误,但因为它太复杂了,我可能一开始就不应该接近 SAX,我遇到了一个令人沮丧的逻辑错误——它有时会输出一个我不感兴趣的值,有时正确地忽略它。这个逻辑错误是唯一阻止我完成项目的原因。我正在尝试调试代码,但这非常令人沮丧,因为即使我的截断测试 XML 文件也有 42,000 行。
所以我的具体问题是如何查看 XML 文件的哪一行触发了任何给定的 startElement。 startElement 或 ContentHandler 是否有索引或其他东西告诉您它在文件中的位置?
我的一般问题是我怎样才能找到自己做这件事的方法?我可以在 Google 上四处游荡,Stack Overflow 是一个我非常感激的巨大资源,但如果我可以独立调查我正在使用的东西的属性,那会更令人满意。例如,有没有办法,在我的代码中,我可以得到一个列表,列出所有挂在 startElement 或变量或任何东西上的东西,真的。 Len() 告诉我某物有多长,Type() 告诉我它是什么类型。当我不确定我遇到的问题 种类 时,是否还有其他有用的元命令可以求助?
我有点预料到会因为一个问题问两个问题而被骂,但我知道如何提出一般性问题而不会因为太模糊而被骂。
此代码归功于 http://pyxml.sourceforge.net/topics/howto/node12.html。
<collection>
<comic title="Sandman" number='62'>
<writer>Neil Gaiman</writer>
<penciller pages='1-9,18-24'>Glyn Dillon</penciller>
<penciller pages="10-17">Charles Vess</penciller>
</comic>
</collection>
我用下面的代码处理XML:
from xml.sax import saxutils
class FindIssue(saxutils.handler.ContentHandler):
def __init__(self, title, number):
self.search_title, self.search_number = title, number
def startElement(self, name, attrs):
# If it's not a comic element, ignore it
if name != 'comic': return
# Look for the title and number attributes (see text)
title = attrs.get('title', None)
number = attrs.get('number', None)
if (title == self.search_title and number == self.search_number):
print (title, '#' + str(number), 'found')
from xml.sax import make_parser
from xml.sax.handler import feature_namespaces
if __name__ == '__main__':
# Create a parser
parser = make_parser()
# Tell the parser we are not interested in XML namespaces
parser.setFeature(feature_namespaces, 0)
# Create the handler
dh = FindIssue('Sandman', '62')
# Tell the parser to use our handler
parser.setContentHandler(dh)
# Parse the input
parser.parse("test.xml")
这是您的示例的一个版本,它还打印匹配元素的行和列。
import io
from xml.sax import saxutils
from xml.sax import make_parser
from xml.sax.handler import feature_namespaces
class FindIssue(saxutils.handler.ContentHandler):
def __init__(self, title, number):
self.locator = None
self.search_title = title
self.search_number = number
def setDocumentLocator(self, loc):
self.locator = loc
def startElement(self, name, attrs):
if name != "comic":
return
title = attrs.get("title")
number = attrs.get("number")
if title == self.search_title and number == self.search_number:
if self.locator:
print("Line", self.locator.getLineNumber(), "column", self.locator.getColumnNumber())
print(title, "#" + str(number), "found")
# Create a parser
parser = make_parser()
parser.setFeature(feature_namespaces, 0)
issue_finder = FindIssue("Sandman", "62")
parser.setContentHandler(issue_finder)
parser.parse(
io.StringIO(
"""
<collection>
<comic title="Sandman" number='62'>
<writer>Neil Gaiman</writer>
<penciller pages='1-9,18-24'>Glyn Dillon</penciller>
<penciller pages="10-17">Charles Vess</penciller>
</comic>
</collection>
""".strip()
)
)