在java中的字符串xml的节点内转义xml字符

时间:2015-01-07 17:37:57

标签: java xml xml-parsing escaping

我有一串XML数据。我需要转义节点内的值,而不是节点本身。

例如:
    <node1>R&R</node1>
应该逃到:
    <node1>R&amp;R</node1>
不应该逃避:
    &lt;node1&gt;R&amp;R&lt;/node1&gt;

过去几天我一直在研究这个问题,但是没有取得多大成功。我不是Java的专家,但以下是我尝试过的不起作用的东西:

  1. 将字符串xml解析为文档。由于节点中的数据包含无效的xml数据,因此不起作用。
  2. 逃离所有角色。由于接收此数据的程序不接受此格式,因此不起作用。
  3. 转义所有字符,然后解析为文档。引发各种错误。
  4. 非常感谢任何帮助。

4 个答案:

答案 0 :(得分:3)

您可以使用正则表达式匹配来查找有角度的括号之间的所有字符串,并循环/处理每个字符串。在这个例子中,我使用Apache Commons Lang来进行XML转义。

public String sanitiseXml(String xml)
{
    // Match the pattern <something>text</something>
    Pattern xmlCleanerPattern = Pattern.compile("(<[^/<>]*>)([^<>]*)(</[^<>]*>)");

    StringBuilder xmlStringBuilder = new StringBuilder();

    Matcher matcher = xmlCleanerPattern.matcher(xml);
    int lastEnd = 0;
    while (matcher.find())
    {
        // Include any non-matching text between this result and the previous result
        if (matcher.start() > lastEnd) {
            xmlStringBuilder.append(xml.substring(lastEnd, matcher.start()));
        }
        lastEnd = matcher.end();

        // Sanitise the characters inside the tags and append the sanitised version
        String cleanText = StringEscapeUtils.escapeXml10(matcher.group(2));
        xmlStringBuilder.append(matcher.group(1)).append(cleanText).append(matcher.group(3));
    }
    // Include any leftover text after the last result
    xmlStringBuilder.append(xml.substring(lastEnd));

    return xmlStringBuilder.toString();
}

这会查找&lt; something&gt; text&lt; / something&gt;的匹配项,捕获标记名称和包含的文本,清理包含的文本,然后将其重新组合在一起。

答案 1 :(得分:1)

问题是<node1>R&R</node1>不是XML。

  • 使用XML解析器无济于事。 XML解析器的目的是过滤掉这种数据。

  • 您可以尝试使用different parser解析“脏”HTML。

但我认为最好的解决方案是首先获得正确的XML:

  • 使用XML lib修复XML源以创建数据。 (永远不要做String连接来创建XML)

  • 如果为您提供了数据,请创建XML-Schema并坚持输入数据的有效性。

答案 2 :(得分:0)

您所呈现的不是XML。这是XPL。 XPL的结构与XML类似,但允许XML在文本字段中使用“特殊字符”。您可以使用XPL实用程序轻松完成XPL到XML的转换。 http://hll.nu

答案 3 :(得分:-1)

我使用了无名之声的答案,但使用了正则表达式:

Pattern xmlCleanerPattern = Pattern.compile("(<[^<>]*>)(.*)(<\\/[^<>]*>)")

我发现这样可以更好地捕获节点内的所有值