替换>,<和&出现在XML节点内的字符

时间:2013-09-30 20:52:30

标签: java xml regex

我遇到的问题类似于这些主题中描述的问题 1)Replace >, <, & chars that appear inside XML nodes 2)Regular expression to match ">", "<", "&" chars that appear inside XML nodes

我正在寻找一个使用Java的解决方案。 在实践中,我有一个巨大的XML文件(~5 MB),我想用它们各自的实体(转义字符)替换特殊字符,而不更改XML标记。 一个典型的例子应该是:

<tag><anothertag>& < > </anothertag></tag> (before)
<tag><anothertag>&amp; &lt; &gt; </anothertag></tag> (after).

提前致谢

2 个答案:

答案 0 :(得分:2)

我强烈建议您不要使用正则表达式来解析XML,在这种情况下,您根本不应该使用正则表达式。

你需要的是一个好的XML解析器/流转化器框架,例如SAXStaX(由于文件的大小,我会选择后者)。

您基本上会将您阅读的每一个流媒体事件都推送给作家。

在使用您的阅读器实例解析文件时识别characters事件,而不是直接编写它,您将每个符号替换为其实体,并写入替换的String而不是原始符号。

注意:here是一个官方的 StaX 教程,可帮助您入门。 Here是JEE5参考页面,其中包含其他信息。

为什么这样做而不是应用Pattern并使用BufferedReader解析整个文件?

  • 因为性能太差(在{5}文件的每一行Pattern上重新匹配)
  • 因为你的Pattern必须非常复杂(所以,不可读,再次,表现不佳)

有关正则表达式XML解析的更多SO文档VS正确的XML解析here

修改

我没有考虑过一个庞大的,完全格式错误的XML文件的情况。 在这种情况下,流媒体框架可能无法使用,因为正在流式传输的文件首先是不是有效的XML。

如果你已经用尽所有其他选择,你想要闭上你的鼻子,使用BufferedReader,并做这样的事情(需要很多的详细说明 - 不要采取字面意思):

String killMe = "<element>blah < > &</element>";
// only valuable piece of info here: checks for characters within a node
// across multiple lines - again, needs a lot of work
Pattern please = Pattern.compile(">(.+)</", Pattern.MULTILINE);
Matcher iWantToDie = please.matcher(killMe);
while (iWantToDie.find()) {
    System.out.println("Uugh: " + iWantToDie.group(1));
    System.out.println("LT: " + iWantToDie.group(1).replace("<", "&lt;"));
    System.out.println("GT: " + iWantToDie.group(1).replace(">", "&gt;"));
    System.out.println("AND: " + iWantToDie.group(1).replace("&", "&amp;"));
}

输出:

Uugh: blah < > &
LT: blah &lt; > &
GT: blah < &gt; &
AND: blah < > &lt;

答案 1 :(得分:0)

这是一个艰难的问题,因为据我所知,存在类似&gt;等标记的事实。作为XML内容的一部分,您有无效的XML。我最好的建议是找到一个像http://dom4j.sourceforge.net/dom4j-1.6.1/这样的优秀xml解析器,希望它能解决你的问题。