20

要するに; XML ファイルに多くの空の行が生成されています。ファイルを学習させる方法としてそれらを削除する方法を探しています。どうやってやるの ?

詳細な説明については; 私は現在、このXMLファイルを持っています:

<recent>
  <paths>
    <path>path1</path>
    <path>path2</path>
    <path>path3</path>
    <path>path4</path>
  </paths>
</recent>

そして、このJavaコードを使用してすべてのタグを削除し、代わりに新しいタグを追加します:

public void savePaths( String recentFilePath ) {
    ArrayList<String> newPaths = getNewRecentPaths();
    Document recentDomObject = getXMLFile( recentFilePath );  // Get the <recent> element.
    NodeList pathNodes = recentDomObject.getElementsByTagName( "path" );   // Get all <path> nodes.

    //1. Remove all old path nodes :
        for ( int i = pathNodes.getLength() - 1; i >= 0; i-- ) { 
            Element pathNode = (Element)pathNodes.item( i );
            pathNode.getParentNode().removeChild( pathNode );
        }

    //2. Save all new paths :
        Element pathsElement = (Element)recentDomObject.getElementsByTagName( "paths" ).item( 0 );   // Get the first <paths> node.

        for( String newPath: newPaths ) {
            Element newPathElement = recentDomObject.createElement( "path" );
            newPathElement.setTextContent( newPath );
            pathsElement.appendChild( newPathElement );
        }

    //3. Save the XML changes :
        saveXMLFile( recentFilePath, recentDomObject ); 
}

このメソッドを何度も実行した後、正しい結果の XML ファイルを取得しますが、次のように、「paths」タグの後と最初の「path」タグの前に多くの空の行があります。

<recent>
  <paths>





    <path>path5</path>
    <path>path6</path>
    <path>path7</path>
  </paths>
</recent>

誰でもそれを修正する方法を知っていますか?

------------------------------------------- 編集: getXMLFile(. ..)、saveXMLFile(...) コード。

public Document getXMLFile( String filePath ) { 
    File xmlFile = new File( filePath );

    try {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document domObject = db.parse( xmlFile );
        domObject.getDocumentElement().normalize();

        return domObject;
    } catch (Exception e) {
        e.printStackTrace();
    }

    return null;
}

public void saveXMLFile( String filePath, Document domObject ) {
    File xmlOutputFile = null;
    FileOutputStream fos = null;

    try {
        xmlOutputFile = new File( filePath );
        fos = new FileOutputStream( xmlOutputFile );
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
        transformer.setOutputProperty( "{http://xml.apache.org/xslt}indent-amount", "2" );
        DOMSource xmlSource = new DOMSource( domObject );
        StreamResult xmlResult = new StreamResult( fos );
        transformer.transform( xmlSource, xmlResult );  // Save the XML file.
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (TransformerConfigurationException e) {
        e.printStackTrace();
    } catch (TransformerException e) {
        e.printStackTrace();
    } finally {
        if (fos != null)
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }
}
4

11 に答える 11

27

まず、これが発生する理由について説明します。これは、XML ファイルを DOM オブジェクトにロードするために使用されるコードが含まれていないため、少しずれている可能性があります。

ファイルから XML ドキュメントを読み取る場合、DOM 仕様に従って、タグ間の空白は実際には有効な DOM ノードを構成します。したがって、XML パーサーは、このような空白の各シーケンスを (タイプのTEXT) DOM ノードとして扱います。

それを取り除くために、私が考えることができる3つのアプローチがあります:

  • XML をスキーマに関連付けてから、 でsetValidating(true)とともに使用setIgnoringElementContentWhitespace(true)DocumentBuilderFactoryます。

    (注:setIgnoringElementContentWhitespaceパーサーが検証モードの場合にのみ機能するため、 を使用する必要がありますsetValidating(true))

  • 空白のみのノードを除外して、すべてのノードを処理する XSL を記述しますTEXT
  • これを行うには Java コードを使用します。XPath を使用してすべての空白のみのTEXTノードを検索し、それらを繰り返し処理して、親からそれぞれを削除します ( を使用getParentNode().removeChild())。次のようにします ( docDOM ドキュメント オブジェクトになります)。

    XPath xp = XPathFactory.newInstance().newXPath();
    NodeList nl = (NodeList) xp.evaluate("//text()[normalize-space(.)='']", doc, XPathConstants.NODESET);
    
    for (int i=0; i < nl.getLength(); ++i) {
        Node node = nl.item(i);
        node.getParentNode().removeChild(node);
    }
    
于 2012-10-01T08:57:24.480 に答える
4

古い「パス」ノードをすべて削除した後、このコードを使用してこれを修正できました。

while( pathsElement.hasChildNodes() )
    pathsElement.removeChild( pathsElement.getFirstChild() );

これにより、XML ファイルで生成された空白がすべて削除されます。

上記の役立​​つリンクについてコメントしてくれたMadProgrammerに感謝します。

于 2012-10-01T13:12:48.940 に答える
2

私は同じ問題に直面しましたが、長い間わかりませんでしたが、このブラッドの質問と彼自身の質問に対する彼自身の回答の後、どこに問題があるのか​​ がわかりました.

アイザックが言ったように、ブラッドの答えは本当に完璧ではないので、私は自分の答えを追加する必要があります:

子ノードが何であるかを知らずにやみくもに削除するのは好きではありません

したがって、より良い「解決策」(回避策である可能性が高いため引用)は次のとおりです。

pathsElement.setTextContent("");

これにより、無駄な空白行が完全に削除されます。すべての子ノードを削除するよりも確実に優れています。ブラッド、これはあなたにも役立つはずです。

しかし、これは原因ではなく結果であり、原因ではなくこの効果を取り除く方法がわかりました。

原因: を呼び出すとremoveChild()、この子が削除されますが、削除された子のインデントと改行も残ります。そして、この indent_and_like_break はテキストコンテンツとして扱われます。

したがって、原因を取り除くには、child とその indent を削除する方法を理解する必要があります。これについての私の質問へようこそ。

于 2013-01-10T09:57:14.373 に答える
2

xml をすばやく「クリーン」にする必要がある場合は、このようなものを見ることができます。次に、次のようなメソッドを使用できます。

public static String cleanUp(String xml) {
    final StringReader reader = new StringReader(xml.trim());
    final StringWriter writer = new StringWriter();
    try {
        XmlUtil.prettyFormat(reader, writer);
        return writer.toString();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return xml.trim();
}

また、必要に応じて、アンチェチェックの違いを比較するには: XMLUnit

于 2012-10-01T08:45:50.637 に答える
1

DOM 処理 API (DOM4J など) を使用している場合、空行を取り除く非常に簡単な方法があります。

  • 保持したいテキストを変数に入れます(つまりtext
  • を使用してノードテキストを "" に設定しますnode.setText("")
  • ノードテキストをtext使用するように設定しますnode.setText(text)

出来上がり!空行はもうありません。他の回答は、xml出力の余分な空の行が実際にタイプテキストの余分なノードである方法を非常によく示しています。

この手法は、テキスト設定関数の名前が API の名前に合わせて変更されている限り、任意の DOM 解析システムで使用できます。したがって、それをもう少し抽象的に表現する方法です。

お役に立てれば:)

于 2014-05-09T10:00:23.257 に答える
1

私の場合、それを文字列に変換してから、正規表現を実行しました:

        //save as String
        StringWriter writer = new StringWriter();
        StreamResult result = new StreamResult(writer);
        tr.transform(new DOMSource(document), result);
        strResult = writer.toString();

        //remove empty lines 
        strResult = strResult.replaceAll("\\n\\s*\\n", "\n");
于 2021-05-06T14:08:43.647 に答える
0

いくつかの注意事項: 1) XML を操作する (要素を削除する/新しい要素を追加する) 場合、(DOM ではなく) XSLT を使用することを強くお勧めします。 、OutputKeys.INDENT を「no」に設定します。3) XML の単純な後処理 (空白、コメントなどの削除) には、単純な SAX2 フィルターを使用できます。

于 2012-10-01T08:41:05.377 に答える