2008-08-28 23 views
94

Tôi có một tài liệu XML hoàn chỉnh trong một chuỗi và muốn có một đối tượng Document. Google biến tất cả các loại rác. Giải pháp đơn giản nhất là gì? (Trong Java 1.5)Làm cách nào để tải một org.w3c.dom.Document từ XML trong một chuỗi?

Giải pháp Nhờ Matt McMinn, tôi đã giải quyết việc triển khai này. Nó có mức độ linh hoạt đầu vào và độ chi tiết ngoại lệ phù hợp với tôi. (Đó là tốt để biết nếu lỗi đến từ bị thay đổi XML - SAXException - hoặc chỉ xấu IO - IOException.)

public static org.w3c.dom.Document loadXMLFrom(String xml) 
    throws org.xml.sax.SAXException, java.io.IOException { 
    return loadXMLFrom(new java.io.ByteArrayInputStream(xml.getBytes())); 
} 

public static org.w3c.dom.Document loadXMLFrom(java.io.InputStream is) 
    throws org.xml.sax.SAXException, java.io.IOException { 
    javax.xml.parsers.DocumentBuilderFactory factory = 
     javax.xml.parsers.DocumentBuilderFactory.newInstance(); 
    factory.setNamespaceAware(true); 
    javax.xml.parsers.DocumentBuilder builder = null; 
    try { 
     builder = factory.newDocumentBuilder(); 
    } 
    catch (javax.xml.parsers.ParserConfigurationException ex) { 
    } 
    org.w3c.dom.Document doc = builder.parse(is); 
    is.close(); 
    return doc; 
} 
+0

Nó sẽ được tốt đẹp nếu bạn có thể sửa các giải pháp. Sử dụng String.getByptes và InputStream áp đặt các vấn đề i18n. Một người bạn của tôi đã nhận được mã từ đây vì điều đó là sai. May mắn rằng findbugs phát hiện ra vấn đề. Giải pháp chính xác được cung cấp bởi erickson là sử dụng InputSource. –

Trả lời

71

này làm việc cho tôi trong Java 1.5 - Tôi tước ra ngoại lệ cụ thể để có thể đọc.

import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.DocumentBuilder; 
import org.w3c.dom.Document; 
import java.io.ByteArrayInputStream; 

public Document loadXMLFromString(String xml) throws Exception 
{ 
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 

    factory.setNamespaceAware(true); 
    DocumentBuilder builder = factory.newDocumentBuilder(); 

    return builder.parse(new ByteArrayInputStream(xml.getBytes())); 
} 
+27

Như đã lưu ý trong câu trả lời của sylvarking, mã này sử dụng 'getBytes()' mà không xem xét mã hóa. – McDowell

+2

bạn có nghĩa là câu trả lời của erickson không? hoặc có thể ông đổi tên hồ sơ của mình? – rogerdpack

+1

không nên có đúc 'return (Document) builder.parse (new ByteArrayInputStream (xml.getBytes()));' ?? –

132

Ai đó!

Có sự cố nghiêm trọng với mã này vì nó bỏ qua mã hóa ký tự được chỉ định trong String (theo mặc định là UTF-8). Khi bạn gọi String.getBytes(), mã hóa mặc định nền tảng được sử dụng để mã hóa các ký tự Unicode thành byte. Vì vậy, trình phân tích cú pháp có thể nghĩ rằng nó nhận được dữ liệu UTF-8 khi thực tế nó nhận được EBCDIC hoặc một cái gì đó & hellip; không đẹp!

Thay vào đó, sử dụng phương pháp phân tích cú pháp mà phải mất một InputSource, có thể được xây dựng với một Reader, như thế này:

import java.io.StringReader; 
import org.xml.sax.InputSource; 
… 
     return builder.parse(new InputSource(new StringReader(xml))); 

Nó không có vẻ như một vấn đề lớn, nhưng sự thiếu hiểu biết về các vấn đề mã hóa ký tự dẫn đến sự phá hoại mã ngấm ngầm giống y2k.

+3

Vì vậy, đơn giản nhưng khó nắm bắt một giải pháp trên Google. Cảm ơn bạn +1 – pat8719

+5

Tôi nhận ra bây giờ rằng tôi không nên chỉ sao chép và dán câu trả lời được chấp nhận mà là đọc qua. –

+1

Tuyệt vời! Đã lưu cuộc sống của chúng tôi trên JDK8 với tệp setup.encoding sau = ISO-8859_1, javax.servlet.request.encoding = UTF-8 PS câu trả lời được gắn nhãn là công việc không đúng cho chúng tôi – kosta5

9

Chỉ có một vấn đề tương tự, ngoại trừ tôi cần một NodeList chứ không phải tài liệu, đây là những gì tôi đã đưa ra. Đó là chủ yếu là giải pháp tương tự như trước, tăng cường để có được các phần tử gốc xuống như một NodeList và sử dụng gợi ý của erickson của việc sử dụng một InputSource thay vì cho các vấn đề mã hóa ký tự.

private String DOC_ROOT="root"; 
String xml=getXmlString(); 
Document xmlDoc=loadXMLFrom(xml); 
Element template=xmlDoc.getDocumentElement(); 
NodeList nodes=xmlDoc.getElementsByTagName(DOC_ROOT); 

public static Document loadXMLFrom(String xml) throws Exception { 
     InputSource is= new InputSource(new StringReader(xml)); 
     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
     factory.setNamespaceAware(true); 
     DocumentBuilder builder = null; 
     builder = factory.newDocumentBuilder(); 
     Document doc = builder.parse(is); 
     return doc; 
    } 
1

Để thao tác XML trong Java, tôi luôn luôn có xu hướng sử dụng API Transformer:

import javax.xml.transform.Source; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.dom.DOMResult; 
import javax.xml.transform.stream.StreamSource; 

public static Document loadXMLFrom(String xml) throws TransformerException { 
    Source source = new StreamSource(new StringReader(xml)); 
    DOMResult result = new DOMResult(); 
    TransformerFactory.newInstance().newTransformer().transform(source , result); 
    return (Document) result.getNode(); 
} 
Các vấn đề liên quan