9

我正在尝试使用 Stax 编写 XML 数据,其中内容本身是 HTML

如果我尝试

xtw.writeStartElement("contents");
xtw.writeCharacters("<b>here</b>");
xtw.writeEndElement();

我明白了

<contents>&lt;b&gt;here&lt;/b&gt;</contents>

然后我注意到 CDATA 方法并将我的代码更改为:

xtw.writeStartElement("contents");
xtw.writeCData("<b>here</b>");
xtw.writeEndElement();

这次结果是

<contents><![CDATA[<b>here</b>]]></contents>

这仍然不好。我真正想要的是

<contents><b>here</b></contents>

那么是否有一个 XML API/Library 允许我在不进入 CDATA 部分的情况下编写原始文本?到目前为止,我已经查看了 Stax 和 JDom,但他们似乎没有提供这个。

最后,我可能会求助于好的旧 StringBuilder ,但这并不优雅。

更新:

到目前为止,我大多同意答案。但是,<b>here</b>我可以有一个 1MB 的 HTML 文档,而不是我想嵌入到更大的 XML 文档中。你的建议意味着我必须解析这个 HTML 文档才能理解它的结构。如果可能的话,我想避免这种情况。

回答:

这是不可能的,否则您可能会创建无效的 XML 文档。

4

7 回答 7

3

问题是它不是原始文本,它是一个元素,所以你应该写

xtw.writeStartElement("contents");
xtw.writeStartElement("b");
xtw.writeCData("here");
xtw.writeEndElement();
xtw.writeEndElement();
于 2010-06-08T10:20:41.740 回答
1

如果您希望将 XML 作为 XML 而不是作为字符数据包含在内,则必须在某个时候对其进行解析。如果您不想自己手动进行解析,您有两种选择:

(1) 使用外部解析实体——在这种情况下,外部文件将被 XML 解析器拉入并解析。当输出再次被序列化时,它将包含外部文件的内容。

[见http://www.javacommerce.com/displaypage.jsp?name=entities.sql&id=18238 ]

(2) 使用 Xinclude - 在这种情况下,文件必须通过 xinclude 处理器运行,该处理器会将 xinclude 引用合并到输出中。大多数 xslt 处理器以及 xmllint 也会使用适当的选项执行 xinclude。

[参见:http ://www.xml.com/pub/a/2002/07/31/xinclude.html ]

(XSLT 也可以在不使用 XInclude 语法的情况下用于合并文档。XInclude 只是提供了一个标准语法)

于 2010-06-08T17:31:44.700 回答
0

问题不在于“这里”,而在于<b></b>.

<b>元素添加为内容的子元素,您就可以做到这一点。任何像 JDOM 或 DOM4J 这样的库都允许你这样做。一般情况是将内容解析为 XML DOM 并将根元素添加为<contents>.

您不能在 CDATA 部分之外添加转义值。

于 2010-06-08T10:19:45.600 回答
0

如果你的 XML 和 HTML 不是太大,你可以做一个解决方法:

xtw.writeStartElement("contents");
xtw.writeCharacters("anUniqueIdentifierForReplace"); // <--
xtw.writeEndElement();

当您将 XML 作为字符串时:

xmlAsString.replace("anUniqueIdentifierForReplace", yourHtmlAsString);

我知道,这不是很好,但这可以工作。


编辑:当然,您应该检查是否yourHtmlAsString有效。

于 2010-06-08T10:36:56.433 回答
0

如果您想在 XML 文档中嵌入大型 HTML 文档,那么 CDATA imho 是您的最佳选择。这样您就不必了解或处理内部结构,并且您可以稍后将文档类型从 HTML 更改为其他内容,而无需太多麻烦。此外,我认为您不能直接嵌入例如 DOCTYPE 指令(即作为保留 DOCTYPE 指令语义的结构化数据)。它们必须表示为字符。

(这主要是对您的更新的回应,但可惜我没有足够的代表发表评论......)

于 2010-06-08T10:44:48.647 回答
0

我看不出解析要插入到输出中的大 XML 块有什么问题。使用 StAX 解析器对其进行解析,只需编写代码将所有事件转发到您现有的序列化程序(变量“xtw”)。

于 2010-06-08T18:41:24.927 回答
0

如果 html 的 blob 实际上是 xhtml,那么我建议做类似的事情(在伪代码中):

xtw.writeStartElement("contents")
XMLReader  xtr=new XMLReader();
xtr.read(blob);
Dom dom=xtr.getDom();
for(element e:dom){
    xtw.writeElement(e);
}
xtw.writeEndElement();

或类似的东西。我不得不做一次类似的事情,但使用了不同的库。

于 2010-06-08T20:27:47.263 回答