org.w3c.dom.ElementをJavaで文字列形式に出力するにはどうすればよいですか?


89

私が持っているorg.w3c.dom.Element私のメソッドに渡されたオブジェクトを。子ノードを含むxml文字列全体(オブジェクトグラフ全体)を確認する必要があります。を使用できるElementxml形式の文字列に変換できるメソッドを探していSystem.out.printlnます。println()'Element'オブジェクトだけではtoString()、xml形式が出力されず、その子ノードを通過しないため、機能しません。それを行うための独自のメソッドを作成せずに簡単な方法はありますか?ありがとう。

回答:


155

標準のAPIを使い続けたいと仮定して...

DOMImplementationLSを使用できます:

Document document = node.getOwnerDocument();
DOMImplementationLS domImplLS = (DOMImplementationLS) document
    .getImplementation();
LSSerializer serializer = domImplLS.createLSSerializer();
String str = serializer.writeToString(node);

<?xml version = "1.0" encoding = "UTF-16"?>宣言が気になる場合は、代わりにトランスフォーマーを使用できます。

TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
StringWriter buffer = new StringWriter();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.transform(new DOMSource(node),
      new StreamResult(buffer));
String str = buffer.toString();

7
これは、[html:null]を取得していて、HTMLを期待する場合の解決策です。グーグルがうまくいけば答えを索引付けできるように、このコメントを追加しました。
Donal Tobin 2010年

3
LSSerializerを引き続き使用して、「UTF-8」を出力できます。代わりにStringWriterでLSOutputを使用し、エンコードタイプを「UTF- * 8」に設定します
ricosrealm 2011年

1
w3c Documentオブジェクトでも機能します
2013

2
<?xml version="1.0" encoding="UTF-16"?>宣言が面倒です...serializer .getDomConfig().setParameter("xml-declaration", false); 最初のソリューションにこの行を追加することもできます
...– Tarsem Singh 2013

あなたの答えをありがとう、それは本当に素晴らしいです。しかし、問題があります。一致した部分の一部のタグが削除され、それらのテキストコンテンツのみが表示されることがあります。この問題について何か提案はありますか?
epcpu 2018

16

String xml-declaration<?xml version="1.0" encoding="UTF-16"?>なしで取得する単純な4行のコードorg.w3c.dom.Element

DOMImplementationLS lsImpl = (DOMImplementationLS)node.getOwnerDocument().getImplementation().getFeature("LS", "3.0");
LSSerializer serializer = lsImpl.createLSSerializer();
serializer.getDomConfig().setParameter("xml-declaration", false); //by default its true, so set it to false to get String without xml-declaration
String str = serializer.writeToString(node);

2

標準のJAXPAPIではサポートされていないため、この目的でJDomライブラリを使用しました。プリンター機能、フォーマッターオプションなどがあります。http://www.jdom.org/


標準のorg.w3c.domAPIの意図ではないため+1。XMLのブロックをテキストとして使用することに興味がある場合は、通常、正規表現が一致するテキストとして解析しようとします(検索条件が正規表現として簡単に表される場合)。
Cornel Masson 2015年

2

XMLのスキーマがある場合、またはXMLのJAXBバインディングを作成できる場合は、JAXBマーシャラーを使用してSystem.outに書き込むことができます。

import javax.xml.bind.*;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;

@XmlRootElement
public class BoundClass {

    @XmlAttribute
    private String test;

    @XmlElement
    private int x;

    public BoundClass() {}

    public BoundClass(String test) {
        this.test = test;
    }

    public static void main(String[] args) throws Exception {
        JAXBContext jxbc = JAXBContext.newInstance(BoundClass.class);
        Marshaller marshaller = jxbc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
        marshaller.marshal(new JAXBElement(new QName("root"),BoundClass.class,new Main("test")),System.out);
    }
}

2

1つのライナーでjcabi-xmlを試してください。

String xml = new XMLDocument(element).toString();

jcabi-xmlの新しいバージョンは、要素をパラメータとしてサポートせず、ノード/ファイル/文字列のみをサポートします。
Ermintar

1

これはjcabiで行われていることです:

private String asString(Node node) {
    StringWriter writer = new StringWriter();
    try {
        Transformer trans = TransformerFactory.newInstance().newTransformer();
        // @checkstyle MultipleStringLiterals (1 line)
        trans.setOutputProperty(OutputKeys.INDENT, "yes");
        trans.setOutputProperty(OutputKeys.VERSION, "1.0");
        if (!(node instanceof Document)) {
            trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        }
        trans.transform(new DOMSource(node), new StreamResult(writer));
    } catch (final TransformerConfigurationException ex) {
        throw new IllegalStateException(ex);
    } catch (final TransformerException ex) {
        throw new IllegalArgumentException(ex);
    }
    return writer.toString();
}

そしてそれは私のために働きます!


0

VTD-XML、あなたは(そのオフセットと長さによって示されるように)カーソルに渡し、セグメントを取得するために、単一getElementFragment呼び出しを行うことができます...以下は一例です

import com.ximpleware.*;
public class concatTest{
    public static void main(String s1[]) throws Exception {
        VTDGen vg= new VTDGen();
        String s = "<users><user><firstName>some </firstName><lastName> one</lastName></user></users>";
        vg.setDoc(s.getBytes());
        vg.parse(false);
        VTDNav vn = vg.getNav();
        AutoPilot ap = new AutoPilot(vn);
        ap.selectXPath("/users/user/firstName");
        int i=ap.evalXPath();
        if (i!=1){
            long l= vn.getElementFragment();
            System.out.println(" the segment is "+ vn.toString((int)l,(int)(l>>32)));
        }
    }

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.