使用Xpath表达式和jaxb解组XML

我是JAXB的新手,想知道是否有一种方法可以将XML解组为我的响应对象但使用xpath表达式。 问题是我打电话给第三方网络服务,我收到的回复有很多细节。 我不希望将XML中的所有细节映射到我的响应对象。 我只想从xml中映射一些细节,使用特定的XPath表达式将其映射到我的响应对象。 是否有注释可以帮助我实现这一目标?

例如,考虑以下响应

  1 Ian   MG Road     

我只对检索街道名称感兴趣所以我想使用xpath表达式使用’root / record / AddressDetails / street’获取street的值并将其映射到我的响应对象

 public class Response{ // How do i map this in jaxb, I do not wish to map record,id or name elements String street; //getter and setters .... } 

谢谢

注意:我是EclipseLink JAXB(MOXy)的负责人,也是JAXB(JST-222)专家组的成员。

您可以在此用例中使用MOXy的@XmlPath扩展名。

响应

 import javax.xml.bind.annotation.*; import org.eclipse.persistence.oxm.annotations.XmlPath; @XmlRootElement(name="root") @XmlAccessorType(XmlAccessType.FIELD) public class Response{ @XmlPath("record/AddressDetails/street/text()") String street; //getter and setters } 

jaxb.properties

要将MOXy用作JAXB提供程序,您需要在与域模型相同的包中包含一个名为jaxb.properties的文件,并带有以下条目(请参阅: http : //blog.bdoughan.com/2011/05/specifying-eclipselink- moxy-as-your.html )

 javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory 

演示

 import java.io.File; import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Response.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); File xml = new File("src/forum17141154/input.xml"); Response response = (Response) unmarshaller.unmarshal(xml); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(response, System.out); } } 

产量

      MG Road     

了解更多信息

如果你想要的只是街道名称,只需使用XPath表达式将其作为字符串,并忘记JAXB – 复杂的JAXB机制没有添加任何值。

 import javax.xml.xpath.*; import org.xml.sax.InputSource; public class XPathDemo { public static void main(String[] args) throws Exception { XPathFactory xpf = XPathFactory.newInstance(); XPath xpath = xpf.newXPath(); InputSource xml = new InputSource("src/forum17141154/input.xml"); String result = (String) xpath.evaluate("/root/record/AddressDetails/street", xml, XPathConstants.STRING); System.out.println(result); } } 

如果要映射到XML文档的中间,可以执行以下操作:

演示代码

您可以使用StAX解析器前进到要解组的文档部分,然后从那里解组XMLStreamReader

 import javax.xml.bind.*; import javax.xml.stream.*; import javax.xml.transform.stream.StreamSource; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Response.class); XMLInputFactory xif = XMLInputFactory.newFactory(); StreamSource xml = new StreamSource("src/forum17141154/input.xml"); XMLStreamReader xsr = xif.createXMLStreamReader(xml); while(!(xsr.isStartElement() && xsr.getLocalName().equals("AddressDetails"))) { xsr.next(); } Unmarshaller unmarshaller = jc.createUnmarshaller(); JAXBElement response = unmarshaller.unmarshal(xsr, Response.class); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(response, System.out); } } 

响应

域对象上的映射是相对于要映射到的XML文档的片段进行的。

 import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) public class Response{ String street; //getter and setters } 

产量

    MG Road   

了解更多信息