Java 为JAXB.unmarshal()提取XML节点的最简单方法是什么?
我使用Java 为JAXB.unmarshal()提取XML节点的最简单方法是什么?,java,jaxb,cxf,unmarshalling,wsdl2java,Java,Jaxb,Cxf,Unmarshalling,Wsdl2java,我使用cxfcodegenplugin的wsdl2java目标从WSDL生成Java。然后,在测试中,我使用JAXB.unmarshal()从原始webservice XML结果填充类 一个典型的例子是GetAllResponseType response=unmarshal(“get all.xml”,GetAllResponseType.class),使用以下方法: <T> T unmarshal(String filename, Class<T> clazz) th
cxfcodegenplugin
的wsdl2java
目标从WSDL生成Java。然后,在测试中,我使用JAXB.unmarshal()从原始webservice XML结果填充类
一个典型的例子是GetAllResponseType response=unmarshal(“get all.xml”,GetAllResponseType.class)
,使用以下方法:
<T> T unmarshal(String filename, Class<T> clazz) throws Exception {
InputStream body = getClass().getResourceAsStream(filename);
return javax.xml.bind.JAXB.unmarshal(body, clazz);
}
T unmarshal(字符串文件名,类clazz)引发异常{
InputStream body=getClass().getResourceAsStream(文件名);
返回javax.xml.bind.JAXB.unmarshal(body,clazz);
}
问题在于:原始XML响应总是包含信封和正文标记,这些标记不是由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>
...
因此,为了使用JAXB.unmarshal(),我必须
<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());
}
T unmarshal(字符串文件名,类clazz)引发异常{
InputStream=getClass().getResourceAsStream(文件名);
InputStream主体=节点内容(即“n4:body”);
返回javax.xml.bind.JAXB.unmarshal(body,clazz);
}
InputStream nodeContent(InputStream为,字符串名称)引发异常{
DocumentBuilderFactory docFactory=DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder=docFactory.newDocumentBuilder();
Document doc=docBuilder.parse(is);
Node Node=firstNonTextNode(doc.getElementsByTagName(name).item(0).getChildNodes());
返回nodeToStream(node);
}
节点第一个非文本节点(节点列表nl){
对于(int i=0;i
我的问题是:
- 在2中是否有更简单的提取方法?我很想做一个regexp。我尝试了XPath,但不知怎的,我无法让它工作。代码示例会很有帮助
- 我可以让wsdl2java创建Body/Envelope类(3),还是自己创建它们比较容易李>
XmlStreamReader
解析XML,然后将其推进到要解组的元素,并让您的JAXB实现解组该XmlStreamReader
了解更多信息
XMLStreamReader
和“原始”JAXB解组器来解组n4:Body
节点中的节点:
<T> T unmarshal(String filename, Class<T> clazz) throws Exception {
XMLInputFactory xif = XMLInputFactory.newFactory();
XMLStreamReader xsr = xif.createXMLStreamReader(getClass().getResourceAsStream(filename));
xsr.nextTag();
while (!xsr.getLocalName().equals("Body")) {
xsr.nextTag();
}
xsr.nextTag();
Unmarshaller unmarshaller = JAXBContext.newInstance(clazz).createUnmarshaller();
return unmarshaller.unmarshal(xsr, clazz).getValue();
}
T unmarshal(字符串文件名,类clazz)引发异常{
XMLInputFactory xif=XMLInputFactory.newFactory();
XMLStreamReader xsr=xif.createXMLStreamReader(getClass().getResourceAsStream(文件名));
xsr.nextTag();
而(!xsr.getLocalName().equals(“Body”)){
xsr.nextTag();
}
xsr.nextTag();
Unmarshaller Unmarshaller=JAXBContext.newInstance(clazz.createUnmarshaller();
返回unmarshaller.unmarshal(xsr,clazz.getValue();
}
感谢Blaise Doughan在这个问题上的帮助。使用DOMSource
传递节点作为输入。下面的方法将org.w3c.dom.Node
作为输入,并返回未编组的类
private <T> T unmarshal(Node node, Class<T> clazz) throws JAXBException {
XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
Source xmlSource = new DOMSource(node);
Unmarshaller unmarshaller = JAXBContext.newInstance(clazz).createUnmarshaller();
return unmarshaller.unmarshal(xmlSource, clazz).getValue();
}
private T unmarshal(节点,类clazz)抛出jaxbeexception{
XMLInputFactory XMLInputFactory=XMLInputFactory.newFactory();
Source xmlSource=新的DOMSource(节点);
Unmarshaller Unmarshaller=JAXBContext.newInstance(clazz.createUnmarshaller();
返回unmarshaller.unmarshal(xmlSource,clazz.getValue();
}