web-dev-qa-db-ja.com

要素テキストの「&」に関するXML解析の問題

私は次のコードを持っています:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(inputXml)));

そして、解析ステップがスローされます:

SAXParseException: The entity name must immediately follow 
                   the '&' in the entity reference

私のinputXmlに次の '&'があるため:

<Line1>Day & Night</Line1>

私はインバウンドXMLを制御できません。これを安全に/正しく解析するにはどうすればよいですか?

12
Chris Knight

簡単に言うと、入力「XML」は有効なXMLではありません。エンティティはエンコードする必要があります。

<Line1>Day &amp; Night</Line1>

基本的に、これを修正する「適切な」方法は、XMLサプライヤにガベージを提供していることを伝え、themで修正する以外にありません。あなたがそれに対処しなければならないいくつかの恐ろしい状況にある場合、あなたが取るアプローチはおそらくあなたが受け取ると期待される価値の範囲に依存するでしょう。

ドキュメントにエンティティがまったくない場合は、処理前に&&amp;に正規表現で置き換えてください。ただし、一部のエンティティを正しく送信している場合は、これらを照合から除外する必要があります。そして、彼らが実際にエンティティコードを送信したいと思った(つまり、&amp;を送信したが、&amp;amp;を意味した)というまれなチャンスでは、あなたは完全に運が悪いでしょう。

しかしねえ-それはとにかくサプライヤーのせいであり、無効な入力を修正しようとする試みが彼らが望んでいたものと正確に一致しない場合、それに対処するために彼らができる簡単なことがあります。 :-)

35
Andrzej Doyle

入力XMLは有効なXMLではありません。残念ながら、これを解析するためにXMLパーサーを実際に使用することはできません。

テキストをXMLパーサーに渡す前に、テキストを前処理する必要があります。 '& ''&amp; 'に置き換えて文字列置換を行うことはできますが、これは入力内の&のすべての出現をキャッチするわけではありませんが、何かを思い付くことができる場合がありますそうです。

5
Flynn1179

Xml解析の前にTidyフレームワークを使用しました

final StringWriter errorMessages = new StringWriter();
final String res = new TidyChecker().doCheck(html, errorMessages);
...
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(addRoot(html))));  
...

そして、すべてOK

4
Ivan Drizhiruk

inputXMLは文字列ですか?次に、これを使用します。

inputXML = inputXML.replaceAll("&\\s+", "&amp;");
3
Denis Tulskiy