Лучший способ конвертировать XML, чтобы иметь CDATA вокруг текста (в Java) - PullRequest
1 голос
/ 29 апреля 2009

У меня есть странное требование, когда мне нужно взять немного 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 ]

3 голосов
/ 29 апреля 2009

Спасибо за все ваши ответы. Я нашел способ сделать это с помощью dom4j. Моя реализация не работает, если у элементов есть «смешанные» дочерние элементы (то есть текстовый элемент), но в моем случае это не проблема. Это работает, потому что dom4j выведет CDATA, если вы добавите узлы 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;
    }
2 голосов
/ 29 апреля 2009

Вы можете использовать XSLT для этого, если: а) весь текст, который нужно вывести, находится в элементах, б) вам нужны только текстовые узлы, в) вы знаете имена всех элементов, содержащих текст и d) нормально выводить любой текст во всех этих выходных элементах как CDATA. Если все эти случаи верны, то вы можете написать преобразование идентичности и добавить в него этот элемент:

<xsl:output method="xml" cdata-section-elements="elm1 elm2 elm3..."/>

См. рекомендацию W3C XSLT по этому вопросу.

1 голос
/ 29 апреля 2009

Я думаю, что это может работать с XSLT-преобразованием, но я не уверен относительно производительности преобразования. Взгляните на разделы CDATA и XSLT , это может помочь вам.

0 голосов
/ 29 апреля 2009

Принимая готовый xml и синтаксический анализ (с парсером xml), он просто заставит парсер захлебнуться от неэкранированных символов. Единственное решение, которое я могу придумать, - это создать свой собственный анализатор супов тегов, чтобы проанализировать его, изменить и вернуть обратно в xml.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...