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

Posted

技术标签:

【中文标题】如何在 java 中将 org.w3c.dom.Element 输出为字符串格式?【英文标题】:How to I output org.w3c.dom.Element to string format in java? 【发布时间】:2010-11-16 05:12:27 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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

【讨论】:

+1 因为它不是标准 org.w3c.dom API 的意图。如果我对作为文本的 XML 块感兴趣,我通常只是尝试将其解析为带有正则表达式匹配的文本(如果搜索条件很容易表示为正则表达式)。【参考方案2】:

假设您想坚持使用标准 API...

你可以使用DOMImplementationLS:

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

如果 声明困扰您,您可以改用 transformer:

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();

【讨论】:

如果您得到 [html: null] 并期望 HTML,这就是解决方案。添加了此评论,以便谷歌可以有希望地索引答案。 您仍然可以使用 LSSerializer 并输出“UTF-8”。将 LSOutput 与 StringWriter 一起使用,并将编码类型设置为“UTF-*8” 也适用于 w3c Document 对象 <?xml version="1.0" encoding="UTF-16"?> 声明麻烦...我们也可以在第一个解决方案中添加此行serializer .getDomConfig().setParameter("xml-declaration", false); .... 感谢您的回答,这真的很棒。但我有一个问题,有时匹配部分的一些标签被删除,它们的文本内容单独显示。您对这个问题有什么建议吗?【参考方案3】:

如果你有 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);
    

【讨论】:

【参考方案4】:

org.w3c.dom.Element获取String的简单4行代码没有xml声明 (<?xml version="1.0" encoding="UTF-16"?>)

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);

【讨论】:

【参考方案5】:

试试jcabi-xml 一个衬里:

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

【讨论】:

新版本的 jcabi-xml 不支持 Element 作为参数,只支持 Node/File/String。【参考方案6】:

使用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)));
        
    


【讨论】:

【参考方案7】:

这就是我在 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();

它对我有用!

【讨论】:

以上是关于如何在 java 中将 org.w3c.dom.Element 输出为字符串格式?的主要内容,如果未能解决你的问题,请参考以下文章