如何在CDATA之外编写非转义XML

时间:2010-06-08 10:15:41

标签: java xml escaping stax

我正在尝试使用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 /库允许我在不加入CDATA部分的情况下编写原始文本?到目前为止,我已经看过Stax和JDom了,他们似乎没有提供这个。

最后我可能会使用优质的StringBuilder,但这不会很优雅。

更新

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

答案:

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

7 个答案:

答案 0 :(得分:3)

问题在于,它不是原始文本,因此您应该编写

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

答案 1 :(得分:1)

如果您希望将XML包含在AS 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只提供标准语法)

答案 2 :(得分:0)

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

<b>元素添加为内容的子元素,您将能够执行此操作。任何像JDOM或DOM4J这样的库都允许你这样做。一般情况是将内容解析为XML DOM,并将根元素添加为<contents>的子元素。

您无法在CDATA部分之外添加转义值。

答案 3 :(得分:0)

如果您的XML和HTML不是太大,您可以解决方法:

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

当您将XML作为字符串时:

xmlAsString.replace("anUniqueIdentifierForReplace", yourHtmlAsString);

我知道,这不太好,但这可行。


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

答案 4 :(得分:0)

如果要在XML文档中嵌入大型HTML文档,那么CDATA imho就是您的选择。这样您就不必理解或处理内部结构,以后可以轻松地将文档类型从HTML更改为其他内容。另外我认为你无法嵌入,例如DOCTYPE指令直接(即作为保留DOCTYPE指令语义的结构化数据)。它们必须表示为字符。

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

答案 5 :(得分:0)

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

答案 6 :(得分: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();

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