我以这种格式从bugzilla下载xml:
<bugzilla>
<bug>
<bug_id>111</bug_id>
<short_desc>text 1 & 2</short_desc>
</bug>
<bug>
<bug_id>222</bug_id>
<short_desc>text 2 <this is a short desc> </short_desc>
</bug>
</bugzilla>
正如您所看到的,当我尝试使用jaxb解析器解析它时,它失败有两个原因:
for&amp;在第一个标记内(需要更改为&
错误消息:The entity name must immediately follow the '&' in the entity reference.
<this is a short desc>
文字的相同案例。错误消息The entity name must immediately follow the '&' in the entity reference.
但我不明白的是这些都是有效标签的内容。那么为什么验证逻辑正在运行这样的内容。在第二种情况下,它不仅仅是<thisisashortdesc>
的单个标记,它可以抛出实际的有效错误,表示缺少结束标记。但是这种情况之间有空格。
找到下面使用的代码:
文件文件=新文件(&#34; C:\ test \ file.xml&#34;);
JAXBContext jaxbContext = JAXBContext.newInstance(Bugzilla.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Bugzilla bugzillaReport = (Bugzilla) jaxbUnmarshaller.unmarshal(file);
无论如何都要解决这个问题。
答案 0 :(得分:1)
如您所知,必须解析有效的XML,因为HTML中没有模糊匹配。标准解决方案是放置<![CDATA[....]]>
。 ( CDATA 代表字符数据。)
<short_desc><![CDATA[text 1 & 2]]></short_desc>
<short_desc><![CDATA[text 2 <this is a short desc> ]]></short_desc>
这很麻烦,问题是当预期文本而不是CData时,使用是否仍然有效。并且创建正确的XML可能更容易。为此目的,Apache commons还有一个StringEscapeUtils.escapeXml10(String)
。
首先尝试(CDATA)。
String xml = new String(Files.readAllBytes(Paths.get("C:\\test\\file.xml")),
StandardCharsets.UTF_8);
xml = "<?xml version=\"1.0\">\n" + xml;
xml = xml.replace("<short_desc>", "<short_desc><![CDATA[");
xml = xml.replace("</short_desc>", "]]></short_desc>");
jaxbUnmarshaller.unmarshal(new StreamSource(new StringReader(xml)));
请注意,反斜杠\
必须在java String中自动转义。
java 9修复:
xml = xml.replaceAll("(?s)<short_desc>(.*)</short_desc>",
matchResult -> "<short_desc>"
+ StringEscapeUtils.escapeXml10(matchResult.group(1))
+ "</short_desc>");
或没有apache常见语言StringEscapeUtils:
xml = xml.replaceAll("(?s)<short_desc>(.*)</short_desc>",
matchResult -> "<short_desc>"
+ matchResult.group(1)
.replace("&", "&")
.replace("\"", """)
.replace("<", "<")
.replace(">", ">")
+ "</short_desc>");