使用lxml.etree.XSLT,将XML文档转换为HTML文档

前言

碰到一个特殊类型的网站,石河子镇人民政府 ,外观看起来很正常(丑不算不正常),但是打开源码,发现只有XML格式的数据。大致看了一下页面源码,发现和页面展示相关的文件引用结构是这样的:

HomePage (XML) ---+        (看到的页面)
                  |
          index.xsl ---+    (主样式表)
                       |
       system_entity.xsl     (主样式表中导入的样式表 * 2)
            turnpage.xsl

如果使用XSLT根据样式表xsl对XML数据进行转换,需要将全部样式表导入同一命名空间,但是暂时没找到好的处理办法,于是使用最low的方法,将全部xsl样式表合并为一个文本文档。值得注意的是:合并的时候,子文档的声明和根级标签都不能存在。

基本概念

XML教程-菜鸟教程

XSLT教程-菜鸟教程

基本步骤

  1. 获取HomePage的XML源码
  2. 根据HomePage的xsl链接,获取index.xsl源码
  3. 根据index.xsl中的导入样式表链接,获取导入的样式表源码
  4. 将多个导入的子样式表,移除声明和root标签,替换到index.xsl对应的导入行
  5. 使用lxml.etree.XML()分别将XML和XSL文档转换为XML_domXSL_dom
  6. 使用lxml.etree.XSLT()XSL_dom转换为XSLT实例(这是一个callable对象,暂且将它命名为transform
  7. 通过调用transform(XSL_dom)获得result,数据类型为lxml.etree._XSLTResultTree
  8. 可已直接将result写入文件或者通过str(result)转换为字符串,得到的字符串就是最终的HTML源码

使用Python lxml.etree.XSLT 进行转换

上示例面条代码

import re
import urlparse

from lxml import etree
import requests


url = "http://shzz.shz.gov.cn/structure/index"
# 下载XML页面
xml_response = requests.get(url)
xml_response.encoding = "utf-8"
xml_source = xml_response.text
# 将XML转换为dom树
xml_dom = etree.XML(xml_response.content)

# 获取index.xsl的url
index_xsl_href = re.compile(r"<\?xml-stylesheet.*?href=\"(.*?)\"\?>").findall(xml_source)[0]
index_xsl_url = urlparse.urljoin(url, index_xsl_href)
# 下载index.xls源码
index_xsl_resp = requests.get(index_xsl_url)
index_xsl_resp.encoding = "utf-8"
index_xsl_dom = etree.XML(index_xsl_resp.content)
index_xsl_source = etree.tostring(index_xsl_dom, encoding="unicode", method="xml")

# 获得import turnpage.xsl源码
system_entity_href, turnpage_href = re.compile(r"").sub("", turnpage_xsl_source)
system_entity_source = re.compile(r"").sub("", system_entity_source)

# 将两个无根标签的样式表源码,替换到index.xsl的对应导入位置
integrated_xsl_source = re.compile(r'(?u)').sub(turnpage_xsl_source, index_xsl_source)
integrated_xsl_source = re.compile(r'(?u)').sub(system_entity_source, integrated_xsl_source)

# 获得transform
xsl_dom = etree.XML(integrated_xsl_source)
transform = etree.XSLT(xsl_dom)

# 最终转换为HTML,打印出结果
new_xml_result = transform(xml_dom)
print(new_xml_result)

第一次处理这样的问题,还有很多不太理解的地方,欢迎大家指导、指正。

你可能感兴趣的:(使用lxml.etree.XSLT,将XML文档转换为HTML文档)