2013-06-13 24 views
11

này mang lại cho tôi một đối tượng Document với một nút cấp cao nhất không có nút con:làm thế nào để sắp xếp một đối tượng JAXB thành org.w3c.dom.Document?

public static Document getDocument(Object jaxb) 
{ 
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    //dbf.setNamespaceAware(true); 
    Document doc = dbf.newDocumentBuilder().newDocument(); 

    JAXBContext context = JAXBContext.newInstance(jaxb.getClass()); 
    context.createMarshaller().marshal(jaxb, doc); 

    return doc; 
} 

Đây là cách giải quyết, mà dường như còn kém hiệu quả hơn, vì nó chuyển thành String và sau đó đến tài liệu.

public static Document getDocument(Object jaxb) 
{       
    StringWriter writer = new StringWriter();  
    JAXBContext context = JAXBContext.newInstance(jaxb.getClass()); 
    context.createMarshaller().marshal(jaxb, writer); 

    return DocumentBuilderFactory.newInstance().newDocumentBuilder(). 
parse(new InputSource(new StringReader(writer.toString())); 
} 

Có thể thực hiện những gì tôi đang cố gắng hoàn thành không?

+0

Hóa ra rằng vấn đề là không marshalling từ JAXB để tài liệu. Vấn đề là, vì một số lý do, các truy vấn XPath không xác định không gian tên không hoạt động với đối tượng Document được trả về bởi phương thức đầu tiên, nhưng làm việc tốt với đối tượng Document được trả về bởi phương thức thứ hai. Giải pháp - ít nhất là bây giờ - là viết lại các truy vấn Xpath của tôi. –

+0

Như một nhận xét trễ: lý do tại sao các truy vấn XPath không xác định không gian tên đang làm việc nếu bạn phân tích cú pháp dữ liệu marshalled của bạn là do các nhà xây dựng tài liệu được mặc định không nhận biết không gian tên. Khi JAXB xây dựng DOM, các thiết lập DocumentBuilder không liên quan vì không có phân tích cú pháp liên quan. – Michael

Trả lời

13

gì bạn đang làm nên làm việc. Dưới đây là một ví dụ:

Domain Model (Foo)

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Foo { 

    private String bar; 

    public String getBar() { 
     return bar; 
    } 

    public void setBar(String bar) { 
     this.bar = bar; 
    } 

} 

Demo

import javax.xml.bind.*; 
import javax.xml.parsers.*; 
import javax.xml.transform.*; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 

import org.w3c.dom.Document; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     // Create the JAXBContext 
     JAXBContext jc = JAXBContext.newInstance(Foo.class); 

     // Create the Object 
     Foo foo = new Foo(); 
     foo.setBar("Hello World"); 

     // Create the Document 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder db = dbf.newDocumentBuilder(); 
     Document document = db.newDocument(); 

     // Marshal the Object to a Document 
     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.marshal(foo, document); 

     // Output the Document 
     TransformerFactory tf = TransformerFactory.newInstance(); 
     Transformer t = tf.newTransformer(); 
     DOMSource source = new DOMSource(document); 
     StreamResult result = new StreamResult(System.out); 
     t.transform(source, result); 
    } 

} 

Output

<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>Hello World</bar></foo> 
+0

Thử thêm một không gian tên vào tài liệu XML mẫu của bạn và sau đó truy vấn Tài liệu bằng biểu thức Xpath không tính đến các không gian tên tài khoản. Ví dụ: // foo/bar so với // ns: foo/ns: thanh –

+1

@JSmith - Tài liệu là không gian tên nhận thức, bạn nên làm cho không gian tên XPath nhận biết được. Thực tế là bạn thấy hành vi khác nhau khi marshalling để 'DOMSource' so với' Tài liệu' là bằng chứng về điều này. Nếu bạn hoán đổi các nhà cung cấp phân tích cú pháp hoặc JAXB, bạn có thể sẽ thấy các kết quả khác nhau. –

11

thử này

DOMResult res = new DOMResult(); 
    JAXBContext context = JAXBContext.newInstance(obj.getClass()); 
    context.createMarshaller().marshal(obj, res); 
    Document doc = (Document) res.getNode(); 
+0

Chỉ ra rằng vấn đề không phải là marshalling từ JAXB đến tài liệu. Vấn đề là, vì một số lý do, các truy vấn XPath không xác định không gian tên không hoạt động với đối tượng Document được trả về bởi phương thức đầu tiên, nhưng làm việc tốt với đối tượng Document được trả về bởi phương thức thứ hai. Giải pháp - ít nhất là bây giờ - là viết lại các truy vấn Xpath của tôi. –

Các vấn đề liên quan