org.xml.sax.SAXParseException:对实体“T”的引用必须以';'结尾分隔符

时间:2009-12-22 05:52:49

标签: java xml

我正在尝试解析一个包含一些特殊字符的XML文件,例如“&”使用DOM解析器。我得到saxparse异常“对实体的引用必须以分隔符结束”。有没有办法克服这个异常,因为我无法修改XML文件来删除特殊字符,因为它来自不同的应用程序。请建议一种解析此XML文件以获取根元素的方法吗?

提前致谢

这是我正在解析的XML部分

<P>EDTA/THAM WASH 
</P>

<P>jhc ^ 72. METER SOLVENT: Meter 21 LITERS of R. O. WATER through the add line into 
FT-250. Start agitator. 
</P>

<P>R. O. WATER &lt;ZLl LITERS </P>

<P>•     NOTE: The following is a tool control operation. The area within 10 feet of any open vessel or container is under tool control. </P>

<P>-af . 73. CHARGE SOLIDS: Remove any unnecessary items from the tool controlled area. Indicate the numbers of each item that will remain in the tool controlled area during the operation in the IN box of the Tool Control Log. </P>

<P>^___y_ a. To minimize the potential for cross contamination, confirm that no other solids are being charged or packaged in adjacent equipment. </P>

<P>kk k WARNING: Wear protective gloves, air jacket and use local exhaust when handling TROMETHAMINE USP (189400) (THAM) (K-l--Irritant!). The THAM may be dusty. </P>

<P>-&lt;&amp;^b .   Charge 2.1 KG of TROMETHAMINE USP (189400) (THAM) into FT-250 through the top. </P>

<P>TROMETHAMINE USP (189400) (THAM) </P>

<P>Scale ID:     / / 7S </P>

<P>LotNo.:   qy/o^yo^ </P>

<P>Gross:    ^ . S </P>

<P>Tare: 10 ,1 </P>

<P>Net:     J^l </P>

<P>Total:   JL'J </P>

<P><Figure ActualText="&T ">

<ImageData src="images/17PT 07009K_img_1.jpg"/>
&amp;T </Figure>
Checked by </P>

9 个答案:

答案 0 :(得分:27)

正如其他人所说,你的XML肯定是无效的。但是,如果您无法更改生成应用程序并可以添加清理步骤,则以下内容应清理XML:

String clean = xml.replaceAll( "&([^;]+(?!(?:\\w|;)))", "&amp;$1" );

正则表达式正在寻找任何格式错误的实体引用并转发&符号。

具体来说,(?!(?:\\w|;))是一个负向前瞻,使得该匹配停止在任何不是单词字符(a-z,0-9)而不是分号的位置。因此,整个正则表达式从&amp;那不是;直到第一个非单词,非分号字符。

它将除&符号之外的所有内容放在第一个捕获组中,以便可以在替换字符串中引用它。这是1美元。

请注意,这不会修复看起来有效但不是有效的引用。例如,如果你有&amp; T;除非XML实际定义了实体,否则会完全抛出不同类型的错误。

答案 1 :(得分:12)

我不确定我理解这个问题。据我所知,除非你在CDATA内,否则没有结束&的裸;字符无效。

如果您的XML文件不是这样,那么它就无效了,您需要找到另一种解析方法,或者在SAX获取它之前修复它。

如果我在这里误解了一些内容,你应该发布实际XML的样本,以便我们进一步了解。

更新

看起来像:

Figure ActualText="&T "

是违规行。此部分是否在CDATA之内?如果没有,这是有效的XML,你不应该期望SAX能够处理它。

您需要:

  • 更改创建它的应用程序;或
  • 在它被SAX(如果你不能改变那个应用程序)加载到“Figure ActualText="&amp;T "”之类的东西之前修复它;或
  • 找到非SAX方法进行解析。

答案 2 :(得分:8)

有些人可能熟悉错误“在向XML模板添加或更改任何代码时,对实体XX的引用必须以';'分隔符结尾”。有时当我尝试更改或添加一些代码到博客博客的模板(XML)时,我甚至会得到错误。

当我们向XML模板添加任何第三方横幅或小部件时,通常会出现这种错误。我们可以通过对我们添加的代码进行轻微更改来轻松纠正错误!

Just replace “&” with “&amp;” in your HTML/Javascript code!

实施例

Original Code:
<!– Begin Code –>
<script src="http://XXXXXX.com/XXX.php?sid=XXX&br=XXX&dk=XXXXXXXXXXXX" type="text/javascript"/>
<!– End Code –>

Altered Code:

<!– Begin Code –>
<script src="http://XXXXXX.com/XXX.php?sid=XXX&amp;br=XXX&amp;dk=XXXXXXXXXXXX" type="text/javascript"/>
<!– End Code –>

答案 3 :(得分:2)

在PSpeed的上述答案的基础上,以下替换所有正则表达式和替换文本将替换所有未转义的&符号的未转义的&符号。

String clean = xml.replaceAll( ("(&(?!amp;))", "&amp;") );

该模式是一个负向前瞻,可以匹配任何尚未转义的&符号,替换字符串只是一个转义符号。通过使用静态编译的模式,可以进一步优化性能。

private final static Pattern unescapedAmpersands = Pattern.compile("(&(?!amp;))");

...

Matcher m = unescapedAmpersands.matcher(xml);
String xmlWithAmpersandsEscaped = m.replaceAll("&amp;");

答案 4 :(得分:1)

作为一种解决方法,您可以:

  1. 将原始输入中&的所有匹配项替换为&amp;;
  2. 解析它;
  3. 在处理结果的代码中,处理现在获得转义字符的情况(例如&lt;而不是<)。
  4. 根据您正在使用的解析器,您还可以尝试找到负责解析和取消& - 字符串的类,并查看是否可以扩展它/提供您自己的解析器。 (我所说的非常模糊,但细节取决于您使用的工具。)

答案 5 :(得分:1)

您的输入是无效的XML。具体来说,你不能拥有'&amp;'属性值中的字符,除非它是格式正确的字符实体引用的一部分。

AFAIK,你有两个选择:

  • 自己编写一个“不完全是XML”的解析器。我严重怀疑你会找到一个现有的。任何自尊的XML解析器都会拒绝无效的输入。
  • 修复创建此(所谓的)XML的任何内容,以便它不会随机放置'&amp;'在不允许的地方使用的字符。这真的很简单。在构建XML时,请替换“&amp;”不属于“&amp; amp;”
  • 的字符引用的字符

答案 6 :(得分:0)

只需将您的&替换为&amp;即可。

答案 7 :(得分:0)

如果在发布之前使用以下命令,它将起作用。

请在下面的命令中放置您的xml文件名

sed -i "s/&/;/g" *.xml

答案 8 :(得分:0)

作为@PSpeed答案的补充,这是一个完整的解决方案(SAX解析器):

    try {

        InputStream xmlStreamToParse = blob.getBinaryStream();

        // Clean
        BufferedReader br = new BufferedReader(new InputStreamReader(xmlStreamToParse));

        StringBuilder sb = new StringBuilder();

        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line.replaceAll("&([^;]+(?!(?:\\w|;)))", "&amp;$1")); // or whatever you want to clean
        }

        InputStream stream = org.apache.commons.io.IOUtils.toInputStream(sb.toString(), "UTF-8");

        // Parsing
        SAXParserFactory saxFactory = SAXParserFactory.newInstance();
        saxFactory.setNamespaceAware(true);
        SAXParser theParser = saxFactory.newSAXParser();
        XMLReader xmlReader = theParser.getXMLReader();
        LicenceXMLHandler licence = new LicenceXMLHandler();
        xmlReader.setContentHandler(licence);
        xmlReader.parse(new InputSource(stream));

    } catch (SQLException | SAXException | IOException | ParserConfigurationException e) {
        log.error("Error: " + e);
    }

说明:

  • 将Blob转换为InputStream
  • 清理Blob
  • 解析文件(LicenceXMLHandler是解析器类)