現在、私は別の製品から受け取ったXMLの解析を含む機能に取り組んでいます。実際の顧客データに対していくつかのテストを実行することにしましたが、他の製品は無効と見なされるべきユーザーからの入力を許可しているようです。とにかく、私はまだそれを解析する方法を試してみなければなりません。 _javax.xml.parsers.DocumentBuilder
_を使用していますが、入力時に次のようなエラーが表示されます。
_<xml>
...
<description>Example:Description:<THIS-IS-PART-OF-DESCRIPTION></description>
...
</xml>
_
おわかりのように、説明にはその中に無効なタグのように見えるものがあります(_<THIS-IS-PART-OF-DESCRIPTION>
_)。現在、この説明タグはリーフタグであることがわかっており、内部にネストされたタグを含めることはできません。とにかく、これはまだ問題であり、DocumentBuilder.parse(...)
で例外を生成します
私はこれが無効なXMLであることを知っていますが、予想通り無効です。そのような入力を解析する方法に関するアイデアはありますか?
「XML」は無効よりも悪い–それは非整形式; Well Formed vs Valid XMLを参照してください。
違反の予測可能性の非公式の評価は役に立たない。そのテキストデータはXMLではありません。準拠するXMLツールまたはライブラリは、処理に役立ちません。
トレラントマークアップパーサーを使用して XMLとして解析する前に問題をクリーンアップします。
スタンドアロン:xmlstarlet 強力な回復および修復機能 クレジット: RomanPerekhrest
_xmlstarlet fo -o -R -H -D bad.xml 2>/dev/null
_
スタンドアロンおよびC:HTML Tidy はXMLでも機能します。
codecs.EncodedFile()
を使用して不正な文字をクリーンアップする方法については、 この回答 も参照してください。FilterInputStream
は 前処理のクリーンアップ に使用できます。XmlReaderSettings.ConformanceLevel
_ は _ConformanceLevel.Fragment
_ に設定できるため、 XmlReader
読み取り可能 XML整形式解析済みエンティティ ルート要素がありません。XmlReader.ReadToFollowing()
は時々使用できる XMLの構文上の問題の回避策 、ただし規則違反に注意以下の#3の警告。Microsoft.Language.Xml.XMLParser
_ は「エラー耐性」と言われています。データをテキストとして処理しますテキストエディターを使用して手動で、または文字/文字列関数を使用してプログラムで処理します。これをプログラムで行うことは、トリッキーから不可能まで多岐にわたります予測可能と思われるものはそうではないので、-ルール違反はルールに拘束されることはほとんどありません。
preg_replace('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $s);
string.tr("^\u{0009}\u{000a}\u{000d}\u{0020}-\u{D7FF}\u{E000}-\u{FFFD}", ' ')
inputStr.replace(/[^\x09\x0A\x0D\x20-\xFF\x85\xA0-\uD7FF\uE000-\uFDCF\uFDE0-\uFFFD]/gm, '')
アンパサンドの場合、正規表現を使用して一致を_&
_に置き換えます。 クレジット: blhsin 、 デモ
_&(?!(?:#\d+|#x[0-9a-f]+|\w+);)
_
上記の正規表現では、コメントやCDATAセクションは考慮されないことに注意してください。
標準のXMLパーサーは、設計上、無効なXMLを決して受け入れません。
唯一のオプションは、入力を前処理して「予測不可能な」コンテンツを削除するか、解析する前にCDATAでラップすることです。
IMOこれらのケースは JSoup を使用して解決する必要があります。
以下はこの特定のケースに対する実際の答えではありませんが、 ウェブ上のこれ (Coderwallのinuyasha82のおかげです)が見つかりました。このコードビットは、不正な形式のXMLを処理する際に別の同様の問題を引き起こしたので、ここで共有します。
元のウェブサイトと同じように、以下を編集しないでください。
XML形式では、ドキュメントで宣言された一意のルート要素が有効である必要があります。たとえば、有効なxmlは次のとおりです。
<root>
<element>...</element>
<element>...</element>
</root>
しかし、次のようなドキュメントがある場合:
<element>...</element>
<element>...</element>
<element>...</element>
<element>...</element>
これは不正なXMLと見なされるため、多くのxmlパーサーはルート要素がないことを訴える例外をスローします。等。
この例では、その問題を解決し、上記の不正なxmlを正常に解析する方法に関するソリューションがあります。
基本的に、プログラムでルート要素を追加します。
したがって、まず、「不正な形式の」xml(つまりファイル)を含むリソースを開く必要があります。
File file = new File(pathtofile);
次に、FileInputStreamを開きます。
FileInputStream fis = new FileInputStream(file);
その時点でこのストリームをXMLライブラリで解析しようとすると、不正な形式のドキュメント例外が発生します。
次に、3つの要素を持つInputStreamオブジェクトのリストを作成します。
ストリングを含むByteIputStream要素: "" Our FileInputStreamストリングを含むByteInputStream: ""したがって、コードは次のとおりです。
List<InputStream> streams =
Arrays.asList(
new ByteArrayInputStream("<root>".getBytes()),
fis,
new ByteArrayInputStream("</root>".getBytes()));
次に、SequenceInputStreamを使用して、上記で作成したリストのコンテナーを作成します。
InputStream cntr =
new SequenceInputStream(Collections.enumeration(str));
これで、cntrで任意のXMLパーサーライブラリを使用でき、問題なく解析されます。 (Staxライブラリで確認);
受け入れられた答えは良いアドバイスであり、非常に役立つリンクが含まれています。
これを追加したいのですが、 manyother 整形式および/またはDTD無効なXMLのケースは、ISO標準のスーパーセットであるSGMLを使用して修復できますHTMLおよびXML。あなたの場合、うまくいくのは偽のTHIS-IS-PART-OF-DESCRIPTION
要素をSGMLの空要素として使用してから、たとえばosx
プログラム(OpenSP/OpenJade SGMLパッケージの一部)をXMLに変換します。たとえば、osx
に次を指定すると
<!DOCTYPE xml [
<!ELEMENT xml - - ANY>
<!ELEMENT description - - ANY>
<!ELEMENT THIS-IS-PART-OF-DESCRIPTION - - EMPTY>
]>
<xml>
<description>blah blah
<THIS-IS-PART-OF-DESCRIPTION>
</description>
</xml>
適切な形式のXMLを出力して、選択したXMLツールでさらに処理します。
ただし、サンプルスニペットには、xml
またはXML
またはXml
などの文字で始まる要素名がXMLで予約されているため、別の問題があることに注意してください。準拠するXMLパーサーによって受け入れられます。