我有一个奇怪的要求,我需要取一些xml并重新编写它,以便文本节点包装在CDATA中(这适用于不允许正常转义的客户端)。
似乎任何普通的XML库dom4j,jdom,java xml都没有任何内置的支持。有任何想法吗?我可以使用XSLT吗?
我不是很清楚。以下是我将要开始的内容:
<foo>This has an & escaped value</foo>
我需要做的是将其转换为:
<foo><![CDATA[This has an & escaped value]]></foo>
-Dave
答案 0 :(得分:3)
感谢您的所有答案。我找到了使用dom4j做到这一点的方法。如果元素具有“混合”子元素(即文本元素),则我的实现不起作用,但在我的情况下,这不是问题。它的工作原理是因为如果添加CDATA节点,dom4j将输出CDATA:
public void replaceTextWithCdataNoMixedText(Document doc) {
if( doc == null )
return;
replaceTextWithCdata(doc.content());
}
private void replaceTextWithCdata(List content) {
if (content == null)
return;
for (Object o : content) {
if (o instanceof Element) {
Element e = (Element) o;
String t = e.getTextTrim();
if (textNeedsEscaping(t)) {
e.clearContent();
e.addCDATA(t);
} else {
List childContent = e.content();
replaceTextWithCdata(childContent);
}
}
}
}
private boolean textNeedsEscaping(String t) {
if (t == null)
return false;
for (int i = 0; i < t.length(); i++) {
char c = t.charAt(i);
if (c == '<' || c == '>' || c == '&') {
return true;
}
}
return false;
}
答案 1 :(得分:2)
您可以使用XSLT来完成此任务,只要a)您需要输出的所有文本都在元素中,b)您只关心文本节点,c)您知道包含文本的所有元素的名称,和d)可以将所有这些输出元素中的任何文本作为CDATA发出。如果所有这些情况都是真的,那么您可以编写一个标识转换并将此元素添加到它:
<xsl:output method="xml" cdata-section-elements="elm1 elm2 elm3..."/>
有关此主题的信息,请参阅the W3C XSLT recommendation。
答案 2 :(得分:1)
我认为它可以用于XSLT转换,但我不确定转换的性能。看看CDATA Sections and XSLT,它可能会对你有帮助。
答案 3 :(得分:0)
使用premade xml和解析(使用xml解析器),它只会使解析器阻塞未转义的字符。我能想到的唯一解决方案是让你自己的标签汤解析器解析它,修改并将其转储回xml。