2009-05-19 8 views
17

Tôi có hai tài liệu XML mà tôi đã tạo và tôi muốn kết hợp hai tài liệu này bên trong một phong bì mới. Vì vậy, tôi cóJava chắp thêm tài liệu XML vào tài liệu hiện có

<alert-set> 
    <warning>National Weather Service...</warning> 
    <start-date>5/19/2009</start-date> 
    <end-date>5/19/2009</end-date> 
</alert-set> 

<weather-set> 
    <chance-of-rain type="percent">31</chance-of-rain> 
    <conditions>Partly Cloudy</conditions> 
    <temperature type="Fahrenheit">78</temperature> 
</weather-set> 

Những gì tôi muốn làm là kết hợp hai bên trong một nút gốc: < DataSet> tài liệu kết hợp </DataSet>

Tôi đã đã thử tạo tài liệu tạm thời và thay thế trẻ em bằng các nút gốc của tài liệu:

<DataSet> 
    <blank/> 
    <blank/> 
</DataSet> 

Và tôi đã hy vọng thay thế hai khoảng trống bằng các phần tử gốc của hai tài liệu nhưng tôi nhận được "WRONG_DOCUMENT_ERR: Một nút được sử dụng trong một tài liệu khác với một tài liệu đã tạo nó." Tôi đã thử áp dụng và nhập các nút gốc nhưng tôi nhận được cùng một lỗi.

Không có cách nào dễ dàng kết hợp tài liệu mà không phải đọc qua và tạo các phần tử mới cho mỗi nút?

CHỈNH SỬA: Đoạn mã mẫu Chỉ cần cố di chuyển một đến tài liệu "trống" ngay bây giờ ... Hàm importNode và adoptNode không thể nhập/áp dụng nút Tài liệu, nhưng không thể nhập nút phần tử và cây con của nó ... hoặc nếu có, nó dường như không hoạt động để phụ thêm/thay thế.

Document xmlDoc;  //created elsewhere 
    Document weather = getWeather(latitude, longitude); 
    Element weatherRoot = weather.getDocumentElement(); 

    Node root = xmlDoc.getDocumentElement(); 
    Node adopt = weather.adoptNode(weatherRoot); 
    Node imported = weather.importNode(weatherRoot, true); 
    Node child = root.getFirstChild(); 

    root.replaceChild(adopt, child);  //initially tried replacing the <blank/> elements 
    root.replaceChild(imported, child); 

    root.appendChild(adopt); 
    root.appendChild(imported); 
    root.appendChild(adopt.cloneNode(true)); 

Tất cả những ném DOMException: WRONG_DOCUMENT_ERR: Một nút được sử dụng trong một tài liệu khác nhau so với cái mà tạo ra nó.

Tôi nghĩ tôi sẽ phải tìm ra cách sử dụng stax hoặc đọc lại tài liệu và tạo ra các phần tử mới ... Tuy nhiên, dường như quá nhiều công việc chỉ để kết hợp tài liệu.

+0

Bạn có thể đăng mã mẫu cho biết cách bạn đang cố kết hợp chúng không? – Jonik

Trả lời

28

Đó là một chút khó khăn, nhưng ví dụ sau chạy:

public static void main(String[] args) { 

    DocumentImpl doc1 = new DocumentImpl(); 
    Element root1 = doc1.createElement("root1"); 
    Element node1 = doc1.createElement("node1"); 
    doc1.appendChild(root1); 
    root1.appendChild(node1); 

    DocumentImpl doc2 = new DocumentImpl(); 
    Element root2 = doc2.createElement("root2"); 
    Element node2 = doc2.createElement("node2"); 
    doc2.appendChild(root2); 
    root2.appendChild(node2); 

    DocumentImpl doc3 = new DocumentImpl(); 
    Element root3 = doc3.createElement("root3"); 
    doc3.appendChild(root3); 

    // root3.appendChild(root1); // Doesn't work -> DOMException 
    root3.appendChild(doc3.importNode(root1, true)); 

    // root3.appendChild(root2); // Doesn't work -> DOMException 
    root3.appendChild(doc3.importNode(root2, true)); 
} 
+3

Cảm ơn, điều đó hoạt động. Tôi đã nhập nút gốc tài liệu của chính nó thay vì tài liệu mà tôi đang cố gắng kết hợp mọi thứ. Đôi khi nghỉ trưa giải quyết mọi thứ. Cảm ơn. – ravun

7

Tôi biết bạn có vấn đề này được giải quyết đã có, nhưng tôi vẫn muốn mất một đâm vào vấn đề này bằng cách sử dụng XOM thư viện mà tôi hiện đang thử nghiệm (liên quan đến this question), và trong khi làm điều đó, cung cấp một cách tiếp cận khác với câu trả lời của Andreas_D.

(Để đơn giản hóa ví dụ này, tôi đặt <alert-set> của bạn và <weather-set> vào các tập tin riêng biệt, mà tôi đọc vào nu.xom.Document trường hợp.)

import nu.xom.*; 

[...] 

Builder builder = new Builder(); 
Document alertDoc = builder.build(new File("src/xomtest", "alertset.xml")); 
Document weatherDoc = builder.build(new File("src/xomtest", "weatherset.xml")); 
Document mainDoc = builder.build("<DataSet><blank/><blank/></DataSet>", ""); 

Element root = mainDoc.getRootElement(); 
root.replaceChild(
    root.getFirstChildElement("blank"), alertDoc.getRootElement().copy()); 
root.replaceChild(
    root.getFirstChildElement("blank"), weatherDoc.getRootElement().copy()); 

Điều quan trọng là tạo một bản sao của các yếu tố được đưa vào mainDoc ; nếu không bạn sẽ nhận được một khiếu nại rằng "con đã có cha mẹ".

Xuất ra mainDoc nay cho:

<?xml version="1.0" encoding="UTF-8"?> 
<DataSet> 
    <alert-set> 
     <warning>National Weather Service...</warning> 
     <start-date>5/19/2009</start-date> 
     <end-date>5/19/2009</end-date> 
    </alert-set> 
    <weather-set> 
     <chance-of-rain type="percent">31</chance-of-rain> 
     <conditions>Partly Cloudy</conditions> 
     <temperature type="Fahrenheit">78</temperature> 
    </weather-set> 
</DataSet> 

Để thỏa thích của tôi, điều này hóa ra là rất thẳng về phía trước để làm với XOM. Chỉ mất một vài phút để viết điều này, mặc dù tôi chắc chắn là không phải rất có kinh nghiệm với thư viện. (Sẽ dễ dàng hơn nếu không có các phần tử <blank/>, tức là bắt đầu bằng đơn giản là <DataSet></DataSet>.Vì vậy, trừ khi bạn có lý do thuyết phục để chỉ sử dụng các công cụ JDK chuẩn, tôi nhiệt liệt khuyên bạn nên thử XOM vì nó có thể làm cho việc xử lý XML trong Java dễ chịu hơn nhiều.

+0

Cảm ơn rất nhiều. Tôi đã kết thúc làm việc đó mà không có các yếu tố vì chúng là vô nghĩa ... Tôi chỉ đang cố gắng quấn đầu quanh DOM. Tài liệu xây dựng với XOM chắc chắn trông dễ dàng hơn những gì tôi đang làm. Tôi là một thực tập vì vậy tôi chỉ nhận được đôi chân của tôi ướt, nhưng nhìn lại tôi đã có thể nói với hầu hết các mã tôi đã viết chỉ một vài tuần trước đây là khá xấu xí. Tôi đã học được cách sử dụng XSLT và javax.xml.Transform và điều đó đã giúp mọi thứ trở nên dễ dàng hơn rất nhiều. Cảm ơn bạn lần nữa vì đã trả lời và liên kết với XOM. Tôi chắc chắn tôi sẽ sớm sử dụng nó. – ravun

+0

Rất vui được trợ giúp :) Nếu không có các yếu tố , bạn chỉ cần thực hiện root.appendChild (alertDoc.getRootElement(). Copy()) v.v. Nhân tiện, hãy xem http://www.xom.nu/apidocs/nu/xom/xslt/XSLTransform.html để xem liệu XOM có thể giúp bạn với XSLT hay không. – Jonik