- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 XML,需要在 python 中使用 SAX 进行解析。
这是我的 XML 的一小部分:
<MovieRating>
<Movie Id="1">
<Title>Father Figures</Title>
<Duration>01:53:00</Duration>
<Description>Upon learning that their mother has been lying to them for years about their allegedly deceased father, two fraternal twin brothers hit the road in order to find him.</Description>
<Release_Date>2017-12-22</Release_Date>
<Image_URL>https://image.com/1.jpg</Image_URL>
<Country>USA</Country>
<Genres>
<Genre Id="5">
<Title>Comedy</Title>
<Description>None</Description>
</Genre>
</Genres>
</Movies>
</MovieRating>
我正在尝试解析它并将其保存到数据库中,如下所示:
import sqlite3
import xml.sax
class MoviesHandler(xml.sax.ContentHandler):
def __init__(self):
self.sql_attr_name = None
self.sql_attrs = dict()
self.conn = None
def startDocument(self):
self.conn = sqlite3.connect('moviez_sax.db')
c = self.conn.cursor()
c.execute('DROP TABLE IF EXISTS MOVIE')
c.execute('''
CREATE TABLE IF NOT EXISTS Movie (
Id INTEGER NOT NULL,
Title VARCHAR (1000) NOT NULL,
Duration TIME NOT NULL,
Description VARCHAR (5000),
Release_Date DATE NOT NULL,
Image_URL VARCHAR (1000),
Country VARCHAR (150),
PRIMARY KEY (Id)
);''');
def endDocument(self):
self.conn.commit()
self.conn.close()
def startElement(self, xml_name, xml_attrs):
#print("start element", xml_name)
if xml_name.lower() == 'movierating':
pass
if xml_name.lower() == 'movie':
self.sql_attr_name = None
self.sql_attrs = {
'Id' : '',
'Title' : '',
'Duration' : '',
'Description' : '',
'Release_Date' : '',
'Image_URL' : '',
'Country':''
}
self.sql_attrs['Id'] += xml_attrs['Id']
elif xml_name.lower() in ['id', 'title', 'duration', 'description' , 'release_date', 'image_url','country']:
self.sql_attr_name = xml_name
else:
pass
def characters(self, text):
if self.sql_attr_name is not None:
self.sql_attrs[self.sql_attr_name] += text
def endElement(self, xml_name):
if xml_name.lower() == 'movie':
c = self.conn.cursor()
c.execute('INSERT INTO MOVIE(Id,Title,Duration,\
Description,Release_Date,Image_URL, Country) VALUES \
(?,?,?,?,?,?,?)',
(self.sql_attrs['Id'].strip(),
self.sql_attrs['Title'].strip(),
self.sql_attrs['Duration'].strip(),
self.sql_attrs['Description'].strip(),
self.sql_attrs['Release_Date'].strip(),
self.sql_attrs['Image_URL'].strip(),
self.sql_attrs['Country'].strip()))
if __name__ == '__main__':
parser = xml.sax.make_parser()
parser.setContentHandler(MovieRatingHandler())
parser.parse(open('movies.xml','r'))
我的问题是,每当我读取 self.sql_attrs['Title'].strip()
时,它都会从两个节点读取 TITLE 节点:电影和流派
它正在保存两者连接的值。就像在那个例子中一样,我得到的标题值是:
Father Figures \n Comedy
有没有办法指定 SAX 哪个节点标题以及要读取的节点路径?因为我有许多具有相同名称的节点,但我想单独读取“电影”和“流派”并将它们保存在两个不同的表中。
谢谢。
最佳答案
您需要在流派
和电影
的情况下记录事件。然后,您将使用堆栈/列表来推送当前节点。
在这种情况下,您也应该维护一个基于节点的字典。下面只是对代码的更新,不是最有效的代码,但显示了如何扩展示例
import sqlite3
import xml.sax
class MoviesHandler(xml.sax.ContentHandler):
def __init__(self):
self.sql_attr_name = None
self.nodes = []
self.sql_attrs = dict()
self.conn = None
def startDocument(self):
self.conn = sqlite3.connect('moviez_sax.db')
c = self.conn.cursor()
c.execute('DROP TABLE IF EXISTS MOVIE')
c.execute('''
CREATE TABLE IF NOT EXISTS Movie (
Id INTEGER NOT NULL,
Title VARCHAR (1000) NOT NULL,
Duration TIME NOT NULL,
Description VARCHAR (5000),
Release_Date DATE NOT NULL,
Image_URL VARCHAR (1000),
Country VARCHAR (150),
PRIMARY KEY (Id)
);''');
def endDocument(self):
self.conn.commit()
self.conn.close()
def startElement(self, xml_name, xml_attrs):
#print("start element", xml_name)
if xml_name.lower() == 'movierating':
pass
if xml_name.lower() == 'genre':
self.nodes.append(xml_name)
self.sql_attrs[xml_name] = {
'Title': '',
'Description': '',
}
if xml_name.lower() == 'movie':
self.nodes.append(xml_name)
self.sql_attr_name = None
self.sql_attrs[xml_name] = {
'Id' : '',
'Title' : '',
'Duration' : '',
'Description' : '',
'Release_Date' : '',
'Image_URL' : '',
'Country':''
}
self.sql_attrs[xml_name]['Id'] += xml_attrs['Id']
elif xml_name.lower() in ['id', 'title', 'duration', 'description' , 'release_date', 'image_url','country']:
self.sql_attr_name = xml_name
else:
self.sql_attr_name = None
pass
def characters(self, text):
if self.sql_attr_name is None or len(self.nodes) == 0:
return
if self.sql_attrs[self.nodes[-1]] is not None:
self.sql_attrs[self.nodes[-1]][self.sql_attr_name] += text
def endElement(self, xml_name):
if xml_name.lower() in ['movie', 'genre']:
self.nodes.pop()
if xml_name.lower() == 'movie':
c = self.conn.cursor()
c.execute('INSERT INTO MOVIE(Id,Title,Duration,\
Description,Release_Date,Image_URL, Country) VALUES \
(?,?,?,?,?,?,?)',
(self.sql_attrs[xml_name]['Id'].strip(),
self.sql_attrs[xml_name]['Title'].strip(),
self.sql_attrs[xml_name]['Duration'].strip(),
self.sql_attrs[xml_name]['Description'].strip(),
self.sql_attrs[xml_name]['Release_Date'].strip(),
self.sql_attrs[xml_name]['Image_URL'].strip(),
self.sql_attrs[xml_name]['Country'].strip()))
if __name__ == '__main__':
parser = xml.sax.make_parser()
parser.setContentHandler(MoviesHandler())
parser.parse(open('movies.xml','r'))
正如您所看到的调试 session ,标题是正确的
关于python - SAX 混淆 XML 中同名的两个节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49921105/
我一直在尝试为 SAX 解析器设置 UI 线程和处理程序。这是我没有实现 UI 线程和处理程序的解析器: public class AndroidXMLReader extends ListActiv
我正在尝试读取一个大型 XML 文档,并且我想以 block 的形式读取它,而不是 XmlDocument 将整个文件读入内存的方式。我知道我可以使用 XmlTextReader 来做到这一点,但我想
我正在尝试将 11384 个 XML 文件解析到一个 SQLite 数据库中。其中之一: ]> 1 2 我正在使用 SAX 解析器: pub
我需要用 Perl 解析 XML 文件。文件的一部分单独存储,并作为系统实体插入。不过,这个问题很常见。但是我无法获得任何信息来解决它。 ]> &externalContent; 当使
我正在尝试从 xsd 解析 HL7 消息定义。我将模式定义分成两个文件。第一个文件包含实际的消息定义,第二个文件包含消息中的段定义。 我正在尝试调整示例代码以从此处解析 XML https://gis
我正在使用 SAX 解析 MathML 表达式(尽管它是 MathML 的事实可能并不完全相关)。输入字符串示例为 λ 为了让 SAX 解
我正在尝试使用 Java 和 SAX 为 Android 设备解析 XML 文件。我从互联网上获取,在解析它时,我得到一个 ExpatException :字符“é”的格式不正确(无效标记)。有没有办
我正在尝试使用java中的sax读取xml文件。我只获得 endElement 的输出,但无法找出 startElement 出了什么问题。 这是我的处理程序: public class XMLHan
我正在使用 SAX 解析器来解析具有父级及其子级标记的 XML,如下所示:
我正在尝试从 RSS 提要中提取数据。 RSS 链接 - http://www.thehindu.com/sport/?service=rss ? 这是我的默认处理程序的字符方法。 public vo
我尝试执行下面的代码,但我的 SAX 解析器没有调用 startElement 方法。 下面是我的代码: package getTableStructure; import java.util.Lis
我正在满足一项要求,即我需要拆分大型 XML 并进一步处理。 这是 XML 示例,它可以变成单行。 yongjin 这是我的代码: import java.util.Arrays; import ja
我正在尝试将标签的内容放入我的 java Sax 解析器中的变量中。但是,Characters 方法仅返回 Char 数组。有没有办法将 Char 数组转换为 Int??? public void c
我有下面的代码.. System.setProperty("http.proxyHost","176.6.129.25") ; System.setProp
如何使用 SAX 显示树中最大深度的节点名称。该算法很适合我理解这个概念.. 例如,我应该如何使用 startelement、endelement、startdocument、enddocument
有没有可行的方法使用默认的处理程序类来查找对应的XML标签?例如... 1 1 我想使用 startElement() 和 endElement() 方
我想使用 SAX 解析器从 xml 文件中解析一些数据。我的xml如下: Pies & past Fruits 为了解析这些数据,我扩展了 DefaultHandler。 解析后的输出
我正在构建一个创建 XML 的流程(从各种来源并出于我事先不知道的各种目的),并且我希望将生成的 XML 直接注入(inject)到标准 XML 处理中,例如 SAX、StAX和 DOM。我已经完成了
我有一个由 MS Excel 创建的 XML 文件,其中包含如下元素: 22. Department"GS "NAES "ABCDEF"
我在使用 java sax 解析器打开 stackoverflow 帖子 XML 转储时遇到问题。它识别每个元素的结尾,但似乎跳过了 startElement 方法。我使用示例代码: try {
我是一名优秀的程序员,十分优秀!