XML에서 문자열로 org.w3c.dom.Document를로드하려면 어떻게해야합니까? 세분성을 갖추고

문자열에 완전한 XML 문서가 있고 Document객체를 원합니다 . Google은 모든 종류의 쓰레기를 찾아냅니다. 가장 간단한 해결책은 무엇입니까? (Java 1.5에서)

솔루션 Matt McMinn 덕분에 저는이 구현을 결정했습니다. 적절한 수준의 입력 유연성과 예외 세분성을 갖추고 있습니다. (오류가 잘못된 XML에서 발생했는지 아니면 SAXException잘못된 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;
}



답변

이것은 Java 1.5에서 나를 위해 작동합니다-가독성을 위해 특정 예외를 제거했습니다.

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


답변

우와!

이 코드에는에 지정된 문자 인코딩 String(기본적으로 UTF-8)을 무시하기 때문에 잠재적으로 심각한 문제가 있습니다. String.getBytes()플랫폼 을 호출 하면 유니 코드 문자를 바이트로 인코딩하는 데 기본 인코딩이 사용됩니다. 따라서 파서는 실제로 EBCDIC 등을 받고있을 때 UTF-8 데이터를 받고 있다고 생각할 수 있습니다. 예쁘지 않습니다!

대신 다음과 같이 Reader로 구성 할 수있는 InputSource를 사용하는 구문 분석 메서드를 사용합니다.

import java.io.StringReader;
import org.xml.sax.InputSource;

        return builder.parse(new InputSource(new StringReader(xml)));

큰 문제처럼 보이지는 않지만 문자 인코딩 문제를 모르면 y2k와 유사한 교활한 코드 부패가 발생합니다.


답변

문서가 아닌 NodeList가 필요하다는 점을 제외하면 비슷한 문제가 발생했습니다. 여기에 제가 생각해 낸 것이 있습니다. 루트 요소를 NodeList로 가져오고 문자 인코딩 문제 대신 InputSource를 사용하라는 erickson의 제안을 사용하여 이전과 거의 동일한 솔루션입니다.

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


답변

Java에서 XML을 조작하려면 항상 Transformer API를 사용하는 경향이 있습니다.

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


답변