1

我想使用 SAX 或 StAX 读取 XHTML 文件,无论哪种效果最好。但我不希望实体被解决、替换或类似的事情。理想情况下,它们应该保持原样。我不想使用 DTD。

这是一个(可执行的,使用 Scala 2.8.x)示例:

import javax.xml.stream._
import javax.xml.stream.events._
import java.io._

println("StAX Test - "+args(0)+"\n")
val factory = XMLInputFactory.newInstance
factory.setProperty(XMLInputFactory.SUPPORT_DTD, false)
factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false)

println("------")
val xer = factory.createXMLEventReader(new FileReader(args(0)))
val entities = new collection.mutable.ArrayBuffer[String]
while (xer.hasNext) {
    val event = xer.nextEvent
    if (event.isCharacters) {
        print(event.asCharacters.getData)
    } else if (event.getEventType == XMLStreamConstants.ENTITY_REFERENCE) {
        entities += event.asInstanceOf[EntityReference].getName
    }
}
println("------")
println("Entities: " + entities.mkString(", "))

鉴于以下 xhtml 文件...

<html>
    <head>
        <title>StAX Test</title>
    </head>
    <body>
        <h1>Hallo StAX</h1>
        <p id="html">
            &lt;div class=&quot;header&quot;&gt;
        </p>
        <p id="stuff">
            &Uuml;berdies sollte das hier auch als Copyright sichtbar sein: &#169;
        </p>
        Das war's!
    </body>
</html>

...运行scala stax-test.scala stax-test.xhtml将导致:

StAX Test - stax-test.xhtml

------


    StAX Test


    Hallo StAX

      <div class="header">


      berdies sollte das hier auch als Copyright sichtbar sein: ?

    Das war's!

------
Entities: Uuml

因此,所有实体或多或少都已成功替换。不过,我所期望的和我想要的是:

StAX Test - stax-test.xhtml

------


    StAX Test


    Hallo StAX

      &lt;div class=&quot;header&quot;&gt;


      &Uuml;berdies sollte das hier auch als Copyright sichtbar sein: &#169;

    Das war's!

------
Entities: // well, or no entities above and instead:
// Entities: lt, quot, quot, gt, Uuml, #169

这甚至可能吗?我想解析 XHTML,进行一些修改,然后再次将其输出为 XHTML。所以我真的希望实体保留在结果中。

另外我不明白为什么 Uuml 被报告为 EntityReference 事件,而其余的则不是。

4

3 回答 3

2

一点术语:&#x169;是数字字符引用(不是实体),&#auml;是实体引用(不是实体)。

我认为任何 XML 解析器都不会报告对应用程序的数字字符引用——它们总是会被扩展。实际上,您的应用程序不应该关心这一点,就像它关心属性之间有多少空白一样。

至于实体引用,SAX 等低级解析接口将报告实体引用的存在——无论如何,它会在它们出现在元素内容中时报告它们,而不是在属性内容中。有些特殊事件只通知 LexicalHandler 而不是 ContentHandler。

于 2011-09-12T12:26:59.603 回答
1

“为什么 Uuml 被报告为 EntityReference 事件而其余的不是”的答案是其余的由 XML 规范定义,而&Uuml;特定于HTML 4.0

由于您的目标是编写修改后的 XHTML,因此可以通过将“编码”设置为“US-ASCII”和/或将“方法”设置为“html”来强制序列化程序发出数字实体引用。XSLT 规范(Java XML 序列化程序的基础)说,当方法是 html 时,序列化程序“可以使用字符实体引用输出字符”。如果不支持命名实体,将编码设置为 ASCII 可能会强制它使用数字实体。

于 2011-09-12T11:59:49.440 回答
-2

在 Java 中,我会使用正则表达式。

public static void main(String... args) throws IOException {
  BufferedReader buf = new BufferedReader(new FileReader(args[0]));
  Pattern entity = Pattern.compile("&([^;]+);");
  Set<String> entities = new LinkedHashSet<String>();
  for (String line; (line = buf.readLine()) != null; ) {
    Matcher m = entity.matcher(line);
    while (m.find())
      entities.add(m.group(1));
  }
  buf.close();
  System.out.println("Entities: " + entities);
}

印刷

Entities: [lt, quot, gt, Uuml, #169]
于 2011-09-12T09:52:29.357 回答