【发布时间】:2016-02-06 19:44:23
【问题描述】:
我想修改 JAXB 加载的对象(来自 XML),以便我可以用更新的 XML 将它们编组回磁盘。
现在举个例子:
<Customers>
<Customer id="1" name="Jack">
<Address type="Residence">
<FirstLine>1 saxon Court</FirstLine>
<City>CY</City>
</Address>
</Customer>
<Customer id="2" name="Iain">
<Address type="Residence">
<FirstLine>104 Bank Road</FirstLine>
<City>NY</City>
</Address>
</Customer>
</Customers>
现在我有多个客户,我想使用 XPATH 功能来获取 Customer[@id=2] 对象的句柄,我可以在其中添加/更新地址。
如果我不使用类似 XPATH 的功能,那么 JAXB 生成的类将具有“List<Customer> customer”,我将不得不遍历客户列表以匹配我想要的 Customer[@id=2]。
谁能告诉我如何使用 XPATH 获取 JAXB 生成的对象的对象实例句柄,以便我可以将其编组回来以更新磁盘上的实际 XML。 如果不能通过 JAXB 完成,那么使用具有 XPATH 灵活性的 java 对象读写 XML 的替代解决方案是什么。
使用示例代码更新问题:
以下是示例代码,它显示了我想用 Moxy/JAXB 实现的目标。
package org.soc.test.customers.moxy;
import java.io.File;
import java.util.List;
import javax.xml.bind.*;
public class UnmarshalDemo {
public static void main(String[] args) throws Exception {
org.eclipse.persistence.jaxb.JAXBContext jc = (org.eclipse.persistence.jaxb.JAXBContext) JAXBContext.newInstance(Customer.class);
File instanceDoc = new File("input.xml");
Customer customer = (Customer) jc.createUnmarshaller() .unmarshal(instanceDoc);
List<PhoneNumber> phones = jc.getValueByXPath(customer, "phone-number[@id=\"12\"]", null, List.class);
String customerId = jc.getValueByXPath(customer, "@id", null, String.class);
System.out.println("Customerid " + customerId + " , phone " + (phones==null?"0":phones.size()));
jc.setValueByXPath(customer, "phone-number[@id=\"12\"]/area-code/text()", null, "555");
jc.createMarshaller().marshal(customer, System.out);
}
}
输入 XML:
<?xml version="1.0" encoding="UTF-8"?>
<customer id="1141">
<first-name>Jon</first-name>
<last-name>Smith</last-name>
<phone-number id="11">
<area-code>515</area-code>
<number>2726652</number>
</phone-number>
<phone-number id="12">
<area-code>515</area-code>
<number>2726652</number>
</phone-number>
</customer>
XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="unqualified"
attributeFormDefault="unqualified">
<xs:element name="customer">
<xs:complexType>
<xs:sequence>
<xs:element name="first-name" type="stringMaxSize5"/>
<xs:element name="last-name" type="stringMaxSize5"/>
<xs:element ref="phone-number" maxOccurs="2"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="phone-number">
<xs:complexType>
<xs:sequence>
<xs:element name="area-code" type="stringMaxSize5"/>
<xs:element name="number" type="xs:string"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:simpleType name="stringMaxSize5">
<xs:restriction base="xs:string">
<xs:maxLength value="5"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
jaxb.properties:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
输出: 客户 ID 1141,电话 0
我希望电话号码的列表大小为 1,但它返回 null。
希望这有助于理解我面临的问题。
谢谢 文卡特
【问题讨论】:
-
感谢您向我推荐链接。我已经尝试过使用 Moxy,但尝试不成功。
-
我已经修改了这个问题,以便更好地理解我所面临的问题。提前致谢。