MicroXML 简介,第 2 部分: 利用 MicroLark 处理 MicroXML

试用开拓性 MicroXML 解析器

MicroXML 是一种向后兼容的简化版的 XML。本系列的 第 1 部分:探索 MicroXML 的基本准则 介绍了 MicroXML 的基本原理。MicroXML 被设计为采用简单的语法,可通过许多现代通用解析工具加以处理。John Cowan 开发的 MicroLark 是 Java™ 环境中的一种开放源码 MicroXML 解析器。在本文中,我们将利用示例代码来学习 MicroLark。

Uche Ogbuji, 合作伙伴, Zepheira, LLC

Uche OgbujiUche Ogbuji 是 Zepheira, LLC 的合伙人,这家公司专门提供下一代 Web 技术解决方案。Ogbuji 是 4Suite 的首席开发人员,这是一种用于 XML、RDF 和知识管理应用程序的开放源代码平台;也是 Versa RDF 查询语言的首席开发人员。他是一位出生在尼日利亚的计算机工程师和技术作家,目前定居在科罗拉多的博尔德。可以通过他的 Weblog Copia 进一步了解 Ogbuji 先生。



2012 年 7 月 16 日

概述

MicroXML 是一种向后兼容的 XML 简化版,也是一种新兴的规范。在本系列的第 1 部分 第 1 部分:探索 MicroXML 的基本准则 中,我们介绍了 MicroXML 的基础知识,说明了它与 XML 1.x 和相关标准的不同之处。MicroXML 由 James Clark 提出,John Cowan 创建了它的第一种解析器 MicroLark,从而使这种规范得到了发展。MicroLark 属于开放源码(Apache 2.0 许可)工具,是用 Java 语言编写的,它实现了几种解析模式:推模式、拉模式和树模式。

在本文中,我们将学习解析 MicroXML 格式。我们将利用命令行和示例代码探索 MicroLark 解析器 API 的各个方面。

入门

为跟上本文的示例进度,您需要下载(请参阅 参考资料 部分):

  • microLark.jar,如果您愿意,也可下载其源代码
  • 开放源码的 Jython 解释器

首先,可以在命令行中运行 MicroLark,使用一个 MicroXML 文件作为输入文件。清单 1第 1 部分:探索 MicroXML 的基本准则 中用到的简单文件做出了一些修改。

清单 1. 一个简单的文件
<!DOCTYPE html>
<html lang="en">
  <!-- A comment -->
  <head>
    <title>Welcome page</title>
  </head>
  <body>
    <p>Welcome to <a href="http://ibm.com/developerworks/">IBM developerWorks</a>.</p>
  </body>
</html>

将上述样例保存为 listing1.xml,使用 清单 2 所示的代码将其置入 MicroLark。

清单 2. MicroLark
java -jar microlark.jar listing1.xml

您应看到如 清单 3 所示的输出结果。

清单 3. 输出结果
(html
Alang en
-\n
-  
-\n
-  
(head
-\n
-    
(title
-Welcome page
)title
-\n
-  
)head
-\n
-  
(body
-\n
-    
(p
-Welcome to 
(a
Ahref http://ibm.com/developerworks/
-IBM developerWorks
)a
-.
)p
-\n
-  
)body
-\n
)html

这看起来是否略有不同?清单 3 采用的是一种称为 PYX 的格式,这是 XML 文档的面向行的表示方式,源自 SGML 文档的表示规范。PYX 将通过最小化解析负担的方式呈现 XML 文档中的所有信息。这是一种非常有用的工具,但令人遗憾的是,XML 开发人员常常会忽略它。

MicroLark 的默认操作是将一个 MicroXML 文档转为 PYX 甚至 PYX 的子集,因为 MicroXML 就是 XML 的一个子集。(如需进一步了解 PYX,请参阅参考资料 部分中列出的 “XML 问题:PYX 简介”。)

PYX 格式非常简单。每行的第一个字符表示该行的内容类型。内容并非直接跨行编写,但可能有多行包含相同的内容类型。对于标记属性,属性名称和属性值将直接由空格分隔,不再额外使用引号。清单 4 展示了前缀字符。

清单 4. 前缀字符
(  start-tag
)  end-tag
A  attribute
-  character data (content)
?  processing instruction

图例对应于上述输入。PYX 最大的优点就是能与传承已久、极度有用的 UNIX® 文本处理命令一起使用,例如 grep、awk、sort、sed 和 awk 等。

错误处理

对于任何 XML 或 MicroXML 解析器,都有必要理解在发生输入错误的情况下将出现怎样的情况。清单 5 给出了 第 1 部分:探索 MicroXML 的基本准则 中格式错误的 XML 的示例。

清单 5. 格式错误的 XML
<para>Hello, I claim to be <strong>MicroXML</para>

如果将上述示例保存为 badxml.xml,并通过 MicroLark 运行,就会得到 清单 6 所示输出。

清单 6. 错误处理
$ java -jar microlark.jar badxml.xml
(para
-Hello, I claim to be 
(strong
-MicroXML
!1:50:Unexpected end-tag

MicroLark 首先显示出 PYX 行,随后在遇到匹配错误的标记时立即终止,并显示一条错误消息。输出结果指明了源文件中发生错误的行和列。


解析器 API

大多数用户都希望更进一步探索 MicroLark 解析器。为此,在保证不过度陷入复杂 Java 代码的情况下,您可以使用 Jython,这是一款出色的原型设计工具。Jython 是 Python 语言的一种实现,可生成和执行 Java 字节代码。Jython 允许您利用更加简单的语言与 Java 类和 API 进行交互。

推解析器

如果您熟悉 Simple API for XML (SAX),那么就必然已经熟悉了推接口。要使用 MicroLark 推接口,您需要通过一种与 SAX 非常类似的方法提供类,处理元素、属性和字符数据等各种结构。利用 ContentHandler 接口可以提供这个类。MicroLark 的这个接口提供了一组实用工具类,包括 PyxWriter 在内,该类用于生成如 清单 3 所示的 PYX。

清单 7 是一个简单的 Jython 程序,复制了 MicroLark 的基本命令行操作。

清单 7. PYX
from org.ccil.cowan.microlark import PyxWriter, Parser
from java.lang import System

pw = PyxWriter(System.out)  
f = open(System.in)
p = Parser()     
p.parse(f, pw)

将上述输出保存为 listing4.py,再调用它,如 清单 8 所示。

清单 8. 调用样例
jython -Dpython.path=microlark.jar listing3.py < listing1.xml

专用内容处理器

通常情况下,您需要提供自己的内容处理器类,执行较为专门的任务。清单 9 定义了一个 link_finder 类,它将检查各元素,确定其是否属于 a 元素(HTML 样式的链接)。随后,内容处理器将打印出 href 属性的值。

清单 9. 专用处理器
from org.ccil.cowan.microlark import ContentHandler, Parser

class link_finder(ContentHandler):
    def startElement(self, elem):
        if elem.getName() == u'a':
            print elem.getAttributeValue(u'href')

f = open('listing1.xml')
p = Parser()     
p.parse(f, link_finder())

如果运行 清单 9 中的代码,您将找到文档中惟一的链接,即 http://ibm.com/developerworks/

拉解析器

另外一种解析方法就是拉式方法,即一次请求多个文档,利用实用方法处理得到的表示元素标记或内容的事件。清单 10 使用拉 API 处理与 清单 7 中的拉版本极为相似的文件。

清单 10. 拉 API
from org.ccil.cowan.microlark import Parser

f = open('listing1.xml')
p = Parser()

#Start the pull parse
p.parse(f)

event = None

#Run through all the events in the document
while event != p.END_DOCUMENT:
    #Pull the next event
    event = p.next()
    #Is it an element start tag?
    if event == p.START_ELEMENT:
        #Get the element's information
        elem = p.getElement()
        #Is it an a element?
        if elem.getName() == u'a':
            #Then print the link value
            print elem.getAttributeValue(u'href')

清单中给出了注释,帮助您理解逻辑。输出结果与 清单 7 相同。

树生成器

您可以利用 MicroLark 生成类似于文档对象模型 (DOM) 的树。为此,请使用 Parser 对象的 buildTree() 方法。


演示

第 1 部分:探索 MicroXML 的基本准则 解释了 MicroXML 如何在保持对 XML 命名空间认知的同时尽可能简化问题。MicroLark 跟踪与任何元素或属性相关的命名空间,您可以通过 getNamespacegetAttributeNamespace 方法访问这些信息。前缀和限定名称能帮助您理解相关内容。清单 11 是一个简单的程序,用于解析文件,并在每次遇到新的默认命名空间时发出信号。

清单 11. 遇到默认命名空间
from org.ccil.cowan.microlark import Parser
from java.lang import System

p = Parser()

#Start the pull parse
p.parse(System.in)

event = None
current_namespace = None

#Run through all the events in the document
while event != p.END_DOCUMENT:
    #Pull the next event
    event = p.next()
    #Is it an element start tag?
    if event == p.START_ELEMENT:
        #Get the element's information
        elem = p.getElement()
        #Has the namespace changed?
        if elem.getNamespace() != current_namespace:
            current_namespace = elem.getNamespace()
            #Print the new namespace
            print "Entering default namespace: ", current_namespace

清单 12 是 MicroXML 格式的一个 Atom 文档样例。feed 元素的默认命名空间碑设置为 Atom,div 元素的默认命名空间设置为 XHTML。

清单 12. Atom 文档样例
<feed xmlns="http://www.w3.org/2005/Atom"
      xml:lang="en"
      xml:base="http://copia.ogbuji.net">
  <id>http://copia.ogbuji.net/atom1.0</id>
  <title>Copia</title>
  <updated>2005-07-15T12:00:00Z</updated>
  <author>
    <name>Uche Ogbuji</name>
    <uri>http://uche.ogbuji.net</uri>
  </author>
  <link href="/blog" />
  <link rel="self" href="/blog/atom1.0" />
  <entry>
    <id>http://copia.ogbuji.net/blog/2005-09-16/xhtml</id>
    <title>XHTML tutorial pubbed</title>
    <link href="http://copia.posterous.com/xhtml-tutorial-pubbed"/>
    <category term="xml"/>
    <category term="css"/>
    <category term="xhtml"/>
    <updated>2005-07-15T12:00:00Z</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.ibm.com/developerworks/edu/x-dw-x-xhtml-i.htm">
            "XHTML, step-by-step"
          </a>
        </p>
        <blockquote>
          <p>Start working with Extensible Hypertext Markup Language. In this tutorial,
          author Uche Ogbuji shows you how to use XHTML in practical Web sites.</p>
        </blockquote>
        <p>In this tutorial</p>
        <ul>
          <li>Tutorial introduction</li>
          <li>Anatomy of an XHTML Web page</li>
          <li>Understand the ground rules</li>
          <li>Replace common HTML idioms</li>
          <li>Some practical considerations</li>
          <li>Wrap up</li>
        </ul>
      </div>
    </content>
  </entry>
</feed>

清单 11 中的文件保存为 listing7.py,将 清单 12 中的文件保存为 listing8.xml。通过 Jython 运行这两个文件。您应看到如 清单 13 所示的输出结果。

清单 13. 输出结果
>$ jython -Dpython.path=microlark.jar listing7.py < listing8.xml 
Entering default namespace:  http://www.w3.org/2005/Atom
Entering default namespace:  http://www.w3.org/1999/xhtml

结束语

如果没有切实可用的实现,规范毫无意义可言。必须有人先行一步,实现 MicroXML。John Cowan 通过 MicroLark 迈出了关键的一步。在很大程度上来讲,MicroLark 易于理解,特别是在 Jython 的轻量级框架中更是如此。希望您在阅读本文之后,能够开始试用 MicroXML。

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=XML, Open source, Web development
ArticleID=825939
ArticleTitle=MicroXML 简介,第 2 部分: 利用 MicroLark 处理 MicroXML
publish-date=07162012