使用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
了解更多信息