如何在Java中将org.w3c.dom.Element输出为字符串格式?


89

我有一个org.w3c.dom.Element对象传递给我的方法。我需要查看包括其子节点的整个xml字符串(整个对象图)。我正在寻找一种可以将转换Element为xml格式字符串的方法System.out.println。只是println()在'Element'对象上将不起作用,因为toString()将不会输出xml格式,也不会通过其子节点。有没有一种简单的方法而无需编写自己的方法来做到这一点?谢谢。

Answers:


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,则这是解决方案。添加了此评论,以便Google希望将答案编入索引。
Donal Tobin 2010年

3
您仍然可以使用LSSerializer并输出“ UTF-8”。请改用LSOutput和StringWriter,并将编码类型设置为“ UTF- * 8”
ricosrealm

1
也可以与w3c Document对象一起使用
2013年

2
<?xml version="1.0" encoding="UTF-16"?>声明什么麻烦事了......我们也可以加入这一行serializer .getDomConfig().setParameter("xml-declaration", false); 中第一个解决方案....
塔西姆·辛

感谢您的回答,这真的很棒。但我有一个问题,有时会删除匹配部分的某些标签,而仅显示它们的文本内容。您对此问题有什么建议吗?
epcpu

16

简单的4行代码即可从中获取String 而无需xml-declaration<?xml version="1.0" encoding="UTF-16"?>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

在标准JAXP API中不支持,我为此目的使用了JDom库。它具有打印机功能,格式化程序选项等。http://www.jdom.org/


+1,因为它不是标准org.w3c.dom API的意图。如果我对XML块作为文本感兴趣,我通常会尝试将其解析为带有正则表达式匹配项的文本(如果搜索条件很容易表示为正则表达式)。
Cornel Masson'3

2

如果您具有XML的架构或可以为其创建JAXB绑定,则可以使用JAXB Marshaller写入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

尝试使用一种内衬的jcabi-xml

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

新版本的jcabi-xml不支持将Element作为参数,仅支持Node / File / String。
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)));
        }
    }

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.