1

VTD-XML を使用して xml ファイルを変更しようとしました。xml は Java (JAX-WS) Web サービスから文字列として受信されました。サーバーからの http 応答ヘッダーのコンテンツ タイプは、 text/xmlおよびcharset = utf-8です。

コードは次のとおりです。

private static byte[] getDataFromFile(String filePath) throws IOException {
    File file = new File(filePath);
    FileInputStream fileInputStream = new FileInputStream(file);
    byte[] byteArray = new byte[(int) file.length()];
    fileInputStream.read(byteArray);
    String fileData = new String(byteArray);
    byteArray = fileData.getBytes("UTF-16");
    return byteArray;
}

private static void cutOffXmlByXpath(String xpathQuery, String inputFilePath, String outputFilePath) throws Exception {
    byte[] byteArray = getDataFromFile(inputFilePath);

    VTDGen vg = new VTDGen();
    vg.setDoc(byteArray);
    vg.parse(false);
    VTDNav vn = vg.getNav();

    AutoPilot ap = new AutoPilot(vn);
    ap.selectXPath(xpathQuery);

    XMLModifier xm = new XMLModifier(vn);

    while((ap.evalXPath())!=-1) {
        xm.remove(vn.getElementFragment());
    }

    xm.output(outputFilePath);
}


public static void main(String[] args) {
    try {
        cutOffXmlByXpath("//Part[@identifier != 'ID Page. Interview and Profile Form' and @identifier != 'Reports']", FILE_PATH, OUTPUT_FILE_PATH);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

xml の上の宣言は次のとおりです。

<?xml version="1.0" encoding="utf-16"?>

これが、getDataFromFile()メソッドでUTF-16のファイルからバイトを読み取っている理由です。それ以外の場合、コードはUTF-16 エンコーディングに切り替えることができないことを示す例外をスローします。

上記のコードは次の例外をスローします。

java.lang.IndexOutOfBoundsException
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:345)
at com.ximpleware.XMLModifier.output(XMLModifier.java:2068)
at com.ximpleware.XMLModifier.output(XMLModifier.java:2193)
at Main.cutOffXmlByXpath(Main.java:111)
at Main.main(Main.java:161)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

ファイルのエンコーディングをUTF-8に変更し、それに応じてgetDataFromFile()メソッドを変更すると (つまり、エンコーディングまたはUTF-8 を encoding として指定せずにファイルからバイトを読み取る)、すべて正常に動作します。

どんな助けでも大歓迎です。

4

1 に答える 1

0

最後にすべてを日食にロードしました。最初に取得したバイトは -17 で、バイナリでは 0xef であり、これは無効な BOM 開始バイトです。参考までに、BOM は 0xff 0xfe、または 0xfe 0xff である必要があるため、解析ルーチンで失敗します...

private static byte[] getDataFromFile(String filePath) throws IOException {
        File file = new File(filePath);
        FileInputStream fileInputStream = new FileInputStream(file);
        byte[] byteArray = new byte[(int) file.length()];
        //byteArray[0]=(byte)0xff;
        //byteArray[1]=(byte)0xfe;
        //byteArray[2]=0x00;

        fileInputStream.read(byteArray);

        System.out.println(" first byte "+byteArray[0]);
        System.out.println(" second byte "+byteArray[1]);
        System.out.println(" third byte "+byteArray[2]);
        System.out.println(" length "+file.length());
        return byteArray;
    }

例外ログは次のようになります。

 first byte -17
 second byte -69
 third byte -65
 length 192
com.ximpleware.ParseException: XML decl error: Can't switch encoding to UTF-16
Line Number: 1 Offset: 39
    at com.ximpleware.VTDGen.matchUTFEncoding(VTDGen.java:2241)
    at com.ximpleware.VTDGen.process_dec_attr(VTDGen.java:3385)
    at com.ximpleware.VTDGen.parse(VTDGen.java:2632)
    at DOMTest.removeNode.cutOffXmlByXpath(removeNode.java:28)
    at DOMTest.removeNode.main(removeNode.java:46)
于 2016-03-24T05:29:07.710 に答える