65.9K
CodeProject 正在变化。 阅读更多。
Home

实用 XML (pXML) 的开源解析器

starIconstarIconstarIconstarIconstarIcon

5.00/5 (5投票s)

2021 年 4 月 28 日

CPOL

14分钟阅读

viewsIcon

4422

downloadIcon

112

介绍用于“实用 XML” (pXML) 的开源核心库(读取器和写入器)。

目录

引言

我之前的文章《对更好的 XML/HTML 语法的建议》提出了一个名为 practicalXML (pXML) 的新 XML/HTML 语法。pXML 比 XML 更简洁,并具有其他优点。

在本文中,我将介绍一个 pXML 解析器。该解析器是用 Java 编写的,根据 MIT 协议开源,源代码可在 Github 上找到。本文使用的示例也在 Github 上。

有关 pXML 的更多信息可以在其 网站上找到。

pXML 语法刷新

如果您从未听说过 pXML,您可能想先阅读《对更好的 XML/HTML 语法的建议》。那篇文章介绍了 pXML 并解释了其原理。

以下是《语法比较》章节的摘录

空元素

XML:  <br />
pXML: [br]

带有文本内容的元素

XML:  <summary>text</summary>
pXML: [summary text]

带有子元素的元素

XML:  <ul>
          <li>
              <div>A <i>friendly</i> dog</div>
          </li>
      </ul>

pXML: [ul
          [li
              [div A [i friendly] dog]
          ]
      ]

属性

XML:  <div id="unplug_warning" class="warning big-text">Unplug power cord before opening!</div>
pXML: [div (id=unplug_warning class="warning big-text")Unplug power cord before opening!]

转义

XML:  <note>Watch out for &lt;, &gt;, &quot;, &apos;, &, [, ], and \ characters</note>
pXML: [note Watch out for <, >, ", ', &, \[, \], and \\ characters]    

注释

Single comment:
XML:  <!-- text -->
pXML: [- text -]

Nested comments:
XML:  not supported
pXML: [- text [- nested -] -]

使用示例

在解释解析器是如何实现的之前,让我们先通过一些高级用法示例来看看解析器能做什么。目的是展示 XML 技术如何与 pXML 一起使用。

从 pXML 到 XML 再回来

为了体现 pXML 中的“p”(“p”代表 practical),我们显然需要能够将 pXML 转换为 XML,以及将 XML 转换为 pXML。本章将展示如何执行此操作的示例。

Hello World

从 PXML 到 XML

下面的代码演示了最简单的 pXML 文档 - 一个名为 hello 的空根元素

[hello]

要将 pXML 转换为 XML,在 dev.pxml.core.utilities 包中有一个名为 PXMLToXMLConverter 的实用类。该类包含名为 pXMLFileToXMLFile 的方法,其签名如下

public static void pXMLFileToXMLFile _
( @NotNull File pXMLFile, @NotNull File XMLFile ) throws Exception

该方法是重载的。输入参数可以是 File 类型(如上所示)、PathString 类型。

假设上面的 pXML [hello] 代码存储在文件 hello.pxml 中。以下指令将 hello.pxml 转换为 hello.xml

pXMLFileToXMLFile ( "hello.pxml", "hello.xml" );

不出所料,结果文件 hello.xml 包含以下代码

<?xml version="1.0" encoding="UTF-8"?>
<hello />

包含本文所有源代码示例的完整测试套件可在 Github 仓库中找到。该仓库使用 Gradle 构建工具。

解析器的 Java API 文档可在 pXML 网站上找到。

如果您想在自己的环境中尝试上述示例,可以按以下步骤操作

  • 如果尚未完成,请安装 Java 11 或更高版本。
  • 使用您选择的工具(例如 Gradle、IntellijIdea、Eclipse)或仅使用原生 Java 创建一个 Java 应用程序。
  • 访问 pXML 的 下载页面,下载最新的 .jar 文件,并将其作为依赖项添加到您的 Java 项目中。
  • 修改主类,使其包含以下代码
    package tests.pxml.hello;
    
    import static dev.pxml.core.utilities.PXMLToXMLConverter.*;
    
    public static void main ( String[] args ) {
        
        try {
            pXMLFileToXMLFile ( "input/hello.pxml", "output/hello.xml" );
        } catch ( Exception e ) {
            e.printStackTrace();
        }
    }

    注意

    根据需要修改 tests.pxml.hello 以及两个文件的路径。接受绝对和相对文件路径。相对路径相对于您的工作目录。

  • 创建文件 input/hello.pxml,内容为 [hello]
  • 创建目录 output
  • 执行应用程序。
  • 在编辑器中打开生成的文件 output/hello.xml 以验证其内容。

从 XML 到 PXML

从 XML 转换为 pXML 也很容易。这可以通过类 dev.pxml.core.utilities.XMLToPXMLConverter 中的方法 XMLFileToPXMLFile 来完成。因此,以下两条 Java 语句是将 XML 文件转换为 pXML 文件所需的

import static dev.pxml.core.utilities.XMLToPXMLConverter.*;

XMLFileToPXMLFile ( "input/hello.xml", "output/hello.pxml" );

执行此代码会将文件 input/hello.xml 及其内容

<?xml version="1.0" encoding="UTF-8"?>
<hello />

...转换为 output/hello.pxml 及其以下 pXML 代码

[hello]

任何读取器/写入器

如前所述,方法 pXMLFileToXMLFileXMLFileToPXMLFile 接受文件路径作为输入/输出参数。如果我们想从 URL、string 等其他源读取/写入 XML/pXML 文档,我们可以

  • 使用 PXMLToXMLConverter.pipePXMLReaderToXMLWriter任何 pXML 源(URLFileString 等)读取,并写入 任何 XML 目标(URLFileString 等)。例如,我们可以从 URL 读取 pXML 代码,并将生成的 XML 代码存储为 string

    这是可能的,因为 pipePXMLReaderToXMLWriter 使用标准的 java.io.Reader 来读取 pXML,并使用 java.io.Writer 来写入 XML。

  • 同样,XMLToPXMLConverter.pipeXMLReaderToPXMLWriter 可用于从 任何 XML 源读取,并将结果写入 任何 pXML 目标。

登录表单

让我们创建一个更有用的示例,展示一些常用的 XML 功能。

我们将把 pXML 代码转换为 XML,然后再将生成的 XML 转换回 pXML。如果一切正常,最终的 pXML 代码必须与初始代码相同。

从 PXML 到 XML

这是一个使用嵌套元素、属性、注释和命名空间的 pXML 文档

[form
    [title Login]
    [note Characters \[, \], < and > are not allowed]
    [fields
        [- Two text fields: user and password -]
        [text_entry (id=user) User]
        [text_entry (id=password) Password]
    ]
    [buttons
        [button (type=submit) Ok]
        [button (type=cancel color="light red") Cancel]
    ]

    [ch:checks (xmlns:ch="http://www.example.com")
        [ch:check user.size >= 2]
        [ch:check password.size >= 8]
    ]
]

文件 input/login_form.pxml

如前所述,我们可以使用以下方法将此文件转换为 output/login_form.xml

pXMLFileToXMLFile ( "input/login_form.pxml", "output/login_form.xml" );

执行上述语句后,output/login_form.xml 的内容是

<?xml version="1.0" encoding="UTF-8"?>
<form>
    <title>Login</title>
    <note>Characters [, ], &lt; and &gt; are not allowed</note>
    <fields>
        <!-- Two text fields: user and password -->
        <text_entry id="user">User</text_entry>
        <text_entry id="password">Password</text_entry>
    </fields>
    <buttons>
        <button type="submit">Ok</button>
        <button type="cancel" color="light red">Cancel</button>
    </buttons>

    <ch:checks xmlns:ch="http://www.example.com">
        <ch:check>user.size &gt;= 2</ch:check>
        <ch:check>password.size &gt;= 8</ch:check>
    </ch:checks>
</form>

文件 output/login_form.xml

可以观察到以下语法差异

  • pXML: [title Login]
    XML:  <title>Login</title>

    这说明了 pXML 和 XML 之间最重要的区别,正如在《对更好的 XML/HTML 语法的建议》中所解释的

  • pXML: [note Characters \[, \], < and > are not allowed]
    XML:  <note>Characters [, ], &lt; and &gt; are not allowed</note>

    在这里,我们可以看到在转换过程中如何应用两种方言的转义规则。pXML 使用 \ 作为转义字符(与大多数编程语言一样),而 XML 使用实体。

  • pXML: [- Two text fields: user and password -]
    XML:  <!-- Two text fields: user and password -->

    转换注释的示例。

  • pXML: [text_entry (id=user) User]
    XML:  <text_entry id="user">User</text_entry>

    转换属性的示例。

    注意 pXML 代码中 ) 后的空格,而生成的 XML 中没有。pXML 解析器允许在 ) 后有一个可选的空格,该空格会被忽略。这使得可以写

    [text_entry (id=user) User]

    而不是

    [text_entry (id=user)User]

    ... 这可读性稍差(但仍然是有效的 pXML 代码)。

    写入

    [text_entry(id=user)User]

    ... 也会被正确解析。

  • pXML: [ch:checks (xmlns:ch="http://www.example.com")
              [ch:check user.size >= 2]
    
    XML:  <ch:checks xmlns:ch="http://www.example.com">
              <ch:check>user.size &gt;= 2</ch:check>

    pXML 解析器支持 XML 命名空间。

从 XML 到 PXML

将结果文件 output/login_form.xml 复制到 input/login_form.xml 后,我们可以使用以下方法从 XML 转换回 pXML

XMLFileToPXMLFile ( "input/login_form.xml", "output/login_form.pxml" );

以下是 output/login_form.pxml 的内容

[form 
    [title Login]
    [note Characters \[, \], < and > are not allowed]
    [fields 
        [- Two text fields: user and password -]
        [text_entry (id="user") User]
        [text_entry (id="password") Password]
    ]
    [buttons 
        [button (type="submit") Ok]
        [button (color="light red" type="cancel") Cancel]
    ]

    [ch:checks (xmlns:ch="http://www.example.com") 
        [ch:check user.size >= 2]
        [ch:check password.size >= 8]
    ]
]

文件 output/login_form.pxml

如我们所见,其内容与我们最初的文件 input/login_form.pxml 的内容相同。

但是,有一个小的 语法 差异 - 这个差异不会改变文件中存储的 数据。在新文件中,引号始终用于包围属性值,即使可以省略它们(例如 id="user" 而不是 id=user)。原因是,默认情况下,此示例中使用的 pXML 写入器始终使用引号包围属性值。它不检查值是否可以不带引号写入,因为这会降低性能。在写入器的未来版本中,可以添加一个参数来指示写入器在可能的情况下省略引号。

与 pXML 一起使用的 XML 技术

pXML 解析器最强大的功能是它能够将 pXML 文档读取到标准的 org.w3c.dom.Document Java 对象中。

由于我们有内存中的 Java Document 对象,我们可以使用 Java 原生支持或第三方库和框架提供的所有 XML 扩展。例如,我们可以

  • 使用 XML Schema(W3C)、RELAX NG 或 Schematron 验证文档
  • 以编程方式遍历文档并提取数据
  • 插入、修改和删除元素和属性,并将结果保存为新的 XML 或 pXML 文档
  • 使用 XQuery/XPath 查询文档(搜索值、计算聚合值等)
  • 使用 XSL 转换器转换文档(例如,创建不同结构的 XML 或 pXML 文档,创建纯文本文档等)

我们无法在一篇文章中涵盖所有内容,所以让我们来看看 一些 示例,了解它是如何工作的。

加载/保存“文档”

在 pXML 中使用 XML 技术,关键在于 PXMLToXMLConverter 类中的方法 pXMLToXMLDocument。此方法从任何源(文件、URL、字符串等)读取 pXML 文档,并将其加载到标准的 Java org.w3c.dom.Document 对象中。该方法的签名是

public static Document pXMLToXMLDocument (
    @NotNull Reader pXMLReader, Object pXMLResource ) throws Exception

如所示,该方法使用 Java Reader 来读取 pXML 代码,并返回一个 Document 对象。输入参数 pXMLResource 只是一个可选参数,用于在错误消息中包含资源的名称(例如“文件 foo/bar.pxml 中的错误”)。

如果发生任何错误,将抛出异常。

数据加载后,我们可以对文档执行所有操作:验证、查询、修改、转换等。

与方法 pXMLToXMLDocument 对应的是 XMLToPXMLConverter 类中的 XMLDocumentToPXML。该方法定义为

public static void XMLDocumentToPXML (
    @NotNull Document XMLDocument, @NotNull Writer pXMLWriter ) throws Exception

该方法读取标准的 Java Document 对象,并将 pXML 数据写入任何 Java Writer(例如 FileWriterStringWriter 等)。

验证

验证 XML 数据的一种常见方法是使用 XML Schema。XML Schema 本身就是一个 XML 文档,其中包含 XML 数据文档必须遵守的规则。

这是一个定义书籍列表的简单 XML 文档示例

<?xml version="1.0" encoding="UTF-8"?>
<books>
    <book>
        <isbn>978-0135957059</isbn>
        <title>The Pragmatic Programmer: Your Journey to Mastery</title>
        <price>41.41</price>
    </book>
    <book>
        <isbn>978-0735619678</isbn>
        <title>Code Complete: A Practical Handbook of Software Construction</title>
        <price>45.32</price>
    </book>
    <book>
        <isbn>978-0134685991</isbn>
        <title>Effective Java</title>
        <price>44.10</price>
    </book>
</books>

文件 input/books.xml

使用 pXML 定义的相同数据如下所示

[books
    [book
        [isbn 978-0135957059]
        [title The Pragmatic Programmer: Your Journey to Mastery]
        [price 41.41]
    ]
    [book
        [isbn 978-0735619678]
        [title Code Complete: A Practical Handbook of Software Construction]
        [price 45.32]
    ]
    [book
        [isbn 978-0134685991]
        [title Effective Java]
        [price 44.10]
    ]
]

文件 input/books.pxml

上述 XML 可以使用此 XML Schema 进行验证

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="books">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="book" type="booktype" minOccurs="1" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="booktype">
        <xs:sequence>
            <xs:element name="isbn" type="xs:string"/>
            <xs:element name="title" type="xs:string"/>
            <xs:element name="price" type="xs:decimal"/>
        </xs:sequence>
    </xs:complexType>

</xs:schema>

文件 input/books.xsd

由于 XML Schema 本身就是一个标准的 XML 文档,我们也可以使用 pXML 来定义它,如下所示

[xs:schema (xmlns:xs=http://www.w3.org/2001/XMLSchema)

    [xs:element (name=books)
        [xs:complexType
            [xs:sequence
                [xs:element (name=book type=booktype minOccurs=1 maxOccurs=unbounded)]
            ]
        ]
    ]

    [xs:complexType (name=booktype)
        [xs:sequence
            [xs:element (name=isbn type=xs:string)]
            [xs:element (name=title type=xs:string)]
            [xs:element (name=price type=xs:decimal)]
        ]
    ]
]

文件 input/books.pxsd

因此,有四种可能的组合可以验证数据

数据格式 Schema 格式
XML XML
XML pXML
pXML XML
pXML pXML

每种组合的示例都包含在 示例仓库中。

dev.pxml.core.utilities.XMLSchemaValidator 提供了 static 方法来验证数据。例如,使用 pXML Schema 文档验证 pXML 数据(例如,使用 books.pxsd 验证 books.pxml)可以通过以下单行代码完成

XMLSchemaValidator.validatePXMLFileWithPXMLSchemaFile (
    new File ( "input/books.pxml" ),
    new File ( "input/books.pxsd" ) );

如果数据无效,将抛出异常。例如,如果一本书使用标签 ibn 而不是 isbn,则会报告以下错误

Invalid content was found starting with element 'ibn'. One of '{isbn}' is expected.

转换

XML 转换是另一个非常有用的 XML 功能。它用于将一个 XML 文档转换为另一个文档。输出文档可以是另一个 XML 文档、HTML 文档或任何其他纯文本文档。转换过程由 转换语言 描述。最流行的转换语言是 XSLT,它被定义为一个 XML 文档。

例如,让我们重用上一个“验证”示例中的书籍数据。

[books
    [book
        [isbn 978-0135957059]
        [title The Pragmatic Programmer: Your Journey to Mastery]
        [price 41.41]
    ]
    [book
        [isbn 978-0735619678]
        [title Code Complete: A Practical Handbook of Software Construction]
        [price 45.32]
    ]
    [book
        [isbn 978-0134685991]
        [title Effective Java]
        [price 44.10]
    ]
]

文件 input/books.pxml

现在我们想创建一个 HTML 文档来显示书籍的表格。我们可以使用以下用 XML 编写的 XSLT 文档

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="html" />

<xsl:template match="/">
<html>
    <head>
        <title>Books</title>
        <style>
            table, th, td {
                border: 1px solid #ddd;
                border-collapse: collapse;
            }
            th, td {
                padding: 0.5em;
            }
        </style>
    </head>

    <body>
        <h2>Books</h2>
        <table>
            <tr><th>ISBN</th><th>Title</th><th>Price</th></tr>
            <xsl:for-each select="books/book">
                <tr>
                    <td><xsl:value-of select="isbn"/></td>
                    <td><xsl:value-of select="title"/></td>
                    <td><xsl:value-of select="price"/></td>
                </tr>
            </xsl:for-each>
        </table>
    </body>
</html>
</xsl:template>

</xsl:stylesheet>

文件 input/books.html.xslt

由于 XSLT 文档本身就是一个 XML 文档,我们也可以用 pXML 来定义它

[xsl:stylesheet (xmlns:xsl=http://www.w3.org/1999/XSL/Transform version=1.0)

[xsl:output (method=text)]

[xsl:template (match=/)
<html>
    <head>
        <title>Books</title>
        <style>
            table, th, td {
                border: 1px solid #ddd;
                border-collapse: collapse;
            }
            th, td {
                padding: 0.5em;
            }
        </style>
    </head>

    <body>
        <h2>Books</h2>
        <table>
            <tr><th>ISBN</th><th>Title</th><th>Price</th></tr>
            [xsl:for-each (select=books/book)
                <tr>
                    <td>[xsl:value-of (select=isbn)]</td>
                    <td>[xsl:value-of (select=title)]</td>
                    <td>[xsl:value-of (select=price)]</td>
                </tr>
            ]
        </table>
    </body>
</html>
]
]

文件 input/books.html.pxslt

dev.pxml.core.utilities.XSLTTransformer 提供了 static 方法来转换数据。例如,我们可以用上面的 pXML XSLT 文档转换上面的 pXML 书籍数据,如下所示

XSLTTransformer.transformPXMLFileWithPXMLXSLTFile (
    new File ( "input/books.pxml" ),
    new File ( "input/books.pxslt" ),
    new File ( "output/books.html" ) );

执行上述语句会创建文件 output/books.html,其内容如下

<html>
    <head>
        <title>Books</title>
        <style>
            table, th, td {
                border: 1px solid #ddd;
                border-collapse: collapse;
            }
            th, td {
                padding: 0.5em;
            }
        </style>
    </head>

    <body>
        <h2>Books</h2>
        <table>
            <tr><th>ISBN</th><th>Title</th><th>Price</th></tr>
            
                <tr>
                    <td>978-0135957059</td>
                    <td>The Pragmatic Programmer: Your Journey to Mastery</td>
                    <td>41.41</td>
                </tr>
            
                <tr>
                    <td>978-0735619678</td>
                    <td>Code Complete: A Practical Handbook of Software Construction</td>
                    <td>45.32</td>
                </tr>
            
                <tr>
                    <td>978-0134685991</td>
                    <td>Effective Java</td>
                    <td>44.10</td>
                </tr>
            
        </table>
    </body>
</html>

在 Web 浏览器中,结果看起来像这样

Book table in browser

使用 PML 中的 XML 技术

上一篇文章中的《pXML 前身》章节解释说,pXML 语法源自 Practical Markup Language (PML)。PML 是一种用于创建网页文章和书籍的标记语言。

现在我们可以说 PML 使用 pXML 语法。它还支持 宽松解析,但内部 AST 以 pXML 格式存储。将来,本文介绍的 pXML 解析器将在 PML 中使用。因此,上一章中说明的所有 XML 技术都可以用于 PML 文档。

例如,可以

  • 使用 XQuery 提取 PML 文档中的所有链接
  • 使用 XML 转换器将所有链接保存到 CSV 文件中,该文件可以被任何语言编写的工具读取,以检查死链接。
  • 创建消耗 PML 解析器生成的 AST 的过滤器,然后转换 AST(添加/删除/更改节点),然后再让 PML 生成 HTML 输出。

人们可以轻松想象用户将能够创建和共享各种有用的 PML 扩展。

解析器(读取器)

上一章展示了我们 可以做什么 用 pXML 解析器。现在我们将深入了解 它是如何工作的,以及您如何使用和自定义解析器来满足您自己的特定需求。

注意

解析器的源代码可在 Github 上找到,其 API 在 此处进行文档化。

基于事件

该解析器是 基于事件的。它读取 pXML 文档并生成事件流。解析器本身不对解析的数据执行任何操作。每种类型的事件(例如 onNodeStart, onNodeEnd 等)都由一个回调函数处理。所有回调函数都属于一个事件处理程序对象。在解析之前,客户端代码必须将一个事件处理程序对象传递给解析器。事件处理程序是一个接口,包含每种事件类型的一个回调函数。它定义为 如下

package dev.pxml.core.reader.parser.eventHandler;

import dev.pxml.core.data.node.PXMLNode;
import dev.pxml.core.reader.reader.TextLocation;
import dev.pxml.core.utilities.annotations.NotNull;

public interface IParserEventsHandler<N, R> {

    void onStart() throws Exception;
    void onStop() throws Exception;

    N onRootNodeStart ( @NotNull PXMLNode rootNode ) throws Exception;
    void onRootNodeEnd ( N rootNode ) throws Exception;

    N onNodeStart ( @NotNull PXMLNode node, @NotNull N parentNode ) throws Exception;
    void onNodeEnd ( N node ) throws Exception;

    void onText ( @NotNull String text, @NotNull N parentNode, TextLocation location ) 
                  throws Exception;

    // [- and -] is included in comment
    void onComment ( String comment, @NotNull N parentNode, TextLocation location ) 
                     throws Exception;

    R getResult() throws Exception;
}

类型参数 N 定义了此事件处理程序生成的节点的类型。类型参数 R 定义了解析终止时创建的最终结果的类型。

核心库中包含以下 IParserEventsHandler 的实现

  • CreateDOM_ParserEventHandler

    此处理程序创建一个标准的 Java org.w3c.dom.Document 对象。它是上一章在验证或转换 pXML 文档时使用的处理程序。

  • CreateAST_ParserEventHandler

    除了创建 Document 对象之外,我们还可以使用此处理程序创建 pXML 特定的 AST。最终结果是一个 PXMLNode

  • WriteXML_ParserEventHandler

    如果我们只需要将 pXML 转换为 XML,那么最有效的方法是使用此处理程序。而不是将整个 pXML 文档加载到内部树结构中,每个项目(nameattributetext 等)在解析后立即写入 Java Writer。因此,非常大的文档可以快速转换,而不会消耗内部内存。

  • Logger_ParserEventHandler

    这是一个实用程序处理程序,它将日志数据写入 Java Writer(默认是标准操作系统输出设备)。可用于调试目的。

  • DoNothing_ParserEventHandler

    顾名思义,此处理程序什么也不做。它在以下情况下很有用

    • 我们只想知道解析器是否报告了错误(例如,格式错误的 pXML 文档)

    • 我们不想处理所有事件。在这种情况下,我们可以创建一个继承自该处理程序的事件处理程序,并覆盖我们关心的函数。

  • Timer_ParserEventHandler

    此事件处理程序继承自 DoNothing_ParserEventHandler,并覆盖 onStartonEnd 函数以测量总解析时间。

自定义解析

如果以上处理程序都不适合您的需求,您可以创建一个实现 IParserEventsHandler 的类,并将其传递给实现 AEventStreamParser解析器,从而创建自己的自定义事件处理程序。要开始,您可以查看上一章中提到的实现。

解析器使用 ITokenizer 来读取 pXML 令牌(名称、文本、注释等)。为了最大程度地定制,您可以提供自己的分词器和/或解析器,并将其与 pXML 的核心库一起使用。

解析器属性和功能

  • 该解析器处于 概念验证 状态,尚未准备好投入生产使用。
  • 用 Java 编写
  • 免费且根据 MIT 许可证开源
  • 无依赖
  • 只有一个 +-55 KB 的 .jar 文件
  • 快速(未使用正则表达式)
  • 基于事件。因此内存占用低,即使读取大型文档也是如此。
  • 可以提供自定义事件处理程序。增加了通用性
  • 能够将 pXML 加载到标准的 Java org.w3c.dom.Document 对象中。因此,可以使用所有基于 Document 的 XML 技术(验证、查询、转换等)。
  • 使用标准的 Java Reader / Writer 实现灵活的输入/输出配置

尚未支持的 XML 功能

当前实现中尚未支持以下功能

  • CDATA 部分
  • 处理指令
  • DTD(由 XML Schema 替代;pXML 中不支持)

写入器

除了读取器之外,核心库还包含一个实现了 IPXMLWriter 接口的写入器。通过将标准的 Java java.io.Writer 传递给 PXMLWriter 类的构造函数来创建写入器。然后可以使用 writeEmptyNodewriteTextNodewriteComment 等方法将 pXML 写入任何目标(文件、字符串、URL 等)。写入器负责在需要时使用转义序列。

缩进必须手动完成。未来版本可能包含 美化打印 模式。

摘要

pXML 解析器可用于

  • 读取 pXML 文档
  • 将 pXML 转换为 XML
  • 将 XML 转换为 pXML
  • 在 pXML 文档中使用 XML 技术(验证、查询、修改和转换文档)

为了最大化通用性,解析器会生成一个事件流,该事件流可以被自定义事件处理程序消耗。

核心库还包含一个用于以编程方式编写 pXML 文档的写入器。

历史

  • 2021 年 4 月 28 日:初始版本
© . All rights reserved.