使用 Xpath 表达式和 jaxb 取消编组 XML

2022-09-02 20:44:09

我是 JAXB 的新手,我想知道是否有一种方法可以将 XML 解构到我的响应对象,但使用 xpath 表达式。问题是我正在调用第三方Web服务,并且我收到的响应有很多细节。我不希望将 XML 中的所有详细信息映射到我的响应对象。我只想从xml映射一些细节,使用这些细节,我可以使用特定的XPath表达式获取这些细节,并将这些表达式映射到我的响应对象。有没有一个注释可以帮助我实现这一目标?

例如,请考虑以下响应

<root>
  <record>
    <id>1</id>
    <name>Ian</name>
    <AddressDetails>
      <street> M G Road </street>
    </AddressDetails>
  </record>  
</root>

我只关心检索街道名称,所以我想使用xpath表达式来获取街道的值,使用“根/记录/地址详细信息/街道”并将其映射到我的响应对象

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

谢谢


答案 1

注意:我是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 提供程序,您需要包含一个与域模型相同的包中调用的文件,其中包含以下条目(请参阅:http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.htmljaxb.properties)

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

}

输出

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <record>
      <AddressDetails>
         <street> M G Road </street>
      </AddressDetails>
   </record>
</root>

详细信息


答案 2

如果你想要的只是街道名称,只需使用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);
    }

}

推荐