将xml转换为在文本周围使用CDATA的最佳方法(在java中)

时间:2009-04-29 03:46:22

标签: java xml

我有一个奇怪的要求,我需要取一些xml并重新编写它,以便文本节点包装在CDATA中(这适用于不允许正常转义的客户端)。

似乎任何普通的XML库dom4j,jdom,java xml都没有任何内置的支持。有任何想法吗?我可以使用XSLT吗?

我不是很清楚。以下是我将要开始的内容:

<foo>This has an &amp; escaped value</foo>

我需要做的是将其转换为:

<foo><![CDATA[This has an & escaped value]]></foo>

-Dave

4 个答案:

答案 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。