Was ist die einfachste Möglichkeit zum extrahieren von XML-Knoten für JAXB.unmarshal()?

Ich die wsdl2java Ziel cxf-codegen-plugin zum generieren von Java aus einer WSDL. Dann, in meinen tests, ich benutze JAXB.unmarshal() Auffüllen von Klassen aus einem raw-webservice-XML-Ergebnis.

Ein typisches Beispiel ist GetAllResponseType response = unmarshal("get-all.xml", GetAllResponseType.class) mithilfe der folgenden Methode:

<T> T unmarshal(String filename, Class<T> clazz) throws Exception {
    InputStream body = getClass().getResourceAsStream(filename);
    return javax.xml.bind.JAXB.unmarshal(body, clazz);
}

Das problem ist dieses: Die rohe XML-Antwort immer umhüllen Envelope-und Body-tags generiert werden und nicht als Klassen von wsdl2java:

<n4:Envelope xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:n="http://www.informatica.com/wsdl/"
         xmlns:n4="http://schemas.xmlsoap.org/soap/envelope/" xmlns:n5="http://schemas.xmlsoap.org/wsdl/"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <n4:Body>
    <n:getAllResponse xmlns:n="http://www.informatica.com/wsdl/">
        <n:getAllResponseElement>
           ...
        </n:getAllResponseElement>
    </n:getAllResponse>
  </n4:Body>
</n4:Envelope>

So, in Reihenfolge zu verwenden, JAXB.unmarshal() ich

  1. entweder Streifen entfernt die umliegenden Envelope/Body-tags manuell in get-all.xml
  2. oder extrahieren Sie die getAllResponse Knoten und re-konvertieren es in ein InputStream
  3. oder erstellen Sie den Umschlag und Körper-Klassen

Derzeit mache ich 2, aber es ist eine Menge code:

<T> T unmarshal(String filename, Class<T> clazz) throws Exception {
    InputStream is = getClass().getResourceAsStream(filename);
    InputStream body = nodeContent(is, "n4:Body");
    return javax.xml.bind.JAXB.unmarshal(body, clazz);
}

InputStream nodeContent(InputStream is, String name) throws Exception {
    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
    Document doc = docBuilder.parse(is);
    Node node = firstNonTextNode(doc.getElementsByTagName(name).item(0).getChildNodes());
    return nodeToStream(node);
}

Node firstNonTextNode(NodeList nl) {
    for (int i = 0; i < nl.getLength(); i++) {
        if (!(nl.item(i) instanceof Text)) {
            return nl.item(i);
        }
    }
    throw new RuntimeException("Couldn't find nontext node");
}

InputStream nodeToStream(Node node) throws Exception {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    Source xmlSource = new DOMSource(node);
    Result outputTarget = new StreamResult(outputStream);
    TransformerFactory.newInstance().newTransformer().transform(xmlSource, outputTarget);
    return new ByteArrayInputStream(outputStream.toByteArray());
}

Meine Fragen sind:

  • Gibt es ein einfacher Weg, um die Extraktion in 2? Ich bin geneigt, einfach ein regexp. Ich habe versucht, XPath, aber irgendwie konnte ich es nicht zu funktionieren. Code-Beispiele wären hilfreich.
  • Kann ich wsdl2java zu erstellen, die die Körper - /Umschlag-Klassen (3), oder ist es einfach zu erstellen Sie selbst?
InformationsquelleAutor neu242 | 2013-06-10
Schreibe einen Kommentar