我想使用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">
<div class="header">
</p>
<p id="stuff">
Überdies sollte das hier auch als Copyright sichtbar sein: ©
</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
<div class="header">
Überdies sollte das hier auch als Copyright sichtbar sein: ©
Das war's!
------
Entities: // well, or no entities above and instead:
// Entities: lt, quot, quot, gt, Uuml, #169
这甚至可能吗? 我想解析XHTML,做一些修改,然后再将它输出为XHTML。所以我真的希望实体留在结果中。
另外,我不明白为什么Uuml被报告为EntityReference事件,而其余事件则没有。
答案 0 :(得分:2)
一些术语:ũ
是数字字符引用(不是实体),&#auml;
是实体引用(不是实体)。
我认为任何XML解析器都不会报告应用程序的数字字符引用 - 它们将始终被扩展。实际上,你的应用程序不应该关心这个,而是关心属性之间有多少空格。
对于实体引用,SAX等低级解析接口将报告实体引用的存在 - 无论如何,它会在元素内容中报告它们,但不会在属性内容中报告。有些特殊事件只通知LexicalHandler而不是ContentHandler。
答案 1 :(得分:1)
“为什么Uuml被报告为EntityReference事件而其余部分未被报告”的答案是其余部分由XML规范定义,而Ü
特定于HTML 4.0。
由于您的目标是编写修改后的XHTML,因此可能通过将“encoding”设置为“US-ASCII”和/或“方法”来强制序列化程序发出数字实体引用“to”html“。 XSLT spec(它是Java XML序列化程序的基础)表示当方法为html时,序列化程序“可以使用字符实体引用输出字符”。如果不支持命名实体,则将编码设置为ASCII可能会强制它使用数字实体。
答案 2 :(得分:-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]