6

以下のスクリーンショットのように、テキスト コンテンツを読み取るための何千ものタグを含む XML ファイルがあります。

読み取る XML ファイル

このコードを使用して、すべての「単語」タグのテキストコンテンツを読み取ろうとしています:

String filePath = "...";
File xmlFile = new File( filePath );

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document domObject = db.parse( xmlFile );
domObject.getDocumentElement().normalize();
NodeList categoryNodes = domObject.getElementsByTagName( "category" );   // Get all the <category> nodes.

for (int s = 0; s < categoryNodes.getLength(); s++) {    //Loop on the <category> nodes.
    String categoryName = categoryNodes.item(s).getAttributes().getNamedItem( "name" ).getNodeValue(); 

    if( selectedCategoryName.equals( categoryName ) ) {  //get its words.
        NodeList wordsNodes = categoryNodes.item(s).getChildNodes();

        for( int i = 0; i < wordsNodes.getLength(); i++ ) {
            if( wordsNodes.item( i ).getNodeType() != Node.ELEMENT_NODE ) continue;
            String word = wordsNodes.item( i ).getTextContent();
            categoryWordsList.add( word );  // Some words are read wrong !!
        }

        break;
    }
}

しかし、何らかの理由で、多くの単語が間違った方法で読まれています。例:

"AMK6780KBU" is read as "9826</word"

"ASSI.ABR30326" is read as "rd>ASSI.AEP26"

"ASSI.25066" is read as "SI.4268</6"

ファイルサイズが大きいためかもしれません。空行を追加したり、XML ファイルから空行を削除したりすると、上記の単語以外の単語が正しく読み取られなくなります。これは奇妙なことです。

XML ファイルはここからダウンロードできます。

4

2 に答える 2

3

解決

下記参照 :-)

その過程で私が試したこと

XMLバージョンをから変更すると1.1 -> 1.0、問題が修正されました。私はJavaを使用しています1.6.0_33(@oriqueがコメントで指摘したように)。

私のテストでは、特定の数のノードの後の破損に間違いなく問題があります。どこかに絞り込みましたASSI.MTK69609。その行を含むすべてを削除すると、前の単語の破損が修正されました。

宣言を次のように変更するだけで、破損も解決されます。

<?xml version="1.0">

また、元のソースXML全体を使用しても破損はありませんでした。

同様に、バージョンをそのままにして1.1、ソースから空白ノードを削除すると、結果は期待どおりになります。次に例を示します。

    <word>ASSI.MTK68490</word>
    <word>ASSI.MTK6862617</word>
<word>ASSI.MTK693115</word>
<word>ASSI.MTK69609</word>

目的の出力が得られ、

    <word>ASSI.MTK68490</word>
    <word>ASSI.MTK6862617</word>
    <word>ASSI.MTK693115</word>
    <word>ASSI.MTK69609</word>

破損しています。

一部の行末の「ノード」を削除すると、問題も修正されました。たとえば、

    <word>ASSI.MTK693115</word><word>ASSI.MTK69609</word>

それで、それはすべてバグを指していました、しかしどこで...?最終的にそれはクリックしました!Xerces

Java 1.6(およびおそらく1.7)に同梱されているXercesのバージョンは、古く、古く、古く、バグがあります(たとえば#6760982)。実際、次を追加するだけでテストクラスを破ることができます。

Document domObject = db.parse( xmlFile );
domObject.normalizeDocument(); // <-- causes following Exception

Exception in thread "main" java.lang.NullPointerException
    at com.sun.org.apache.xerces.internal.util.XML11Char.isXML11ValidNCName(XML11Char.java:340)

XML 1.1には多くの欠陥が修正されているので、すぐに最新バージョンをダウンロードしましたXerces2 Java 2.11.0

最新バージョンで実行するだけで、期待される破損のない出力が得られました。

java -classpath .;xercesImpl.jar;xml-apis.jar Foo > foo.txt
于 2013-03-21T15:24:11.480 に答える