有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JAXB具有XPATH灵活性,可在运行时修改对象

我想修改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。特性:

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

输出: Customerid 1141,电话0

我希望电话号码的列表大小为1,但它返回null

希望这有助于理解我所面临的问题

谢谢 文卡特


共 (1) 个答案

  1. # 1 楼答案

    莫西不支持它。org.eclipse.persistence.internal.oxm.Context只支持方括号中的数字索引。虽然XPathFragment理解它并创建适当的谓词,但Context在搜索匹配项时会忽略这些谓词。我要么提出一个错误,要么寻找另一个工具

    请参阅^{}源代码(Commit 7cedaac6cdf9384ae9a06129d6f9abd607f9e3c4,第371行之后),以了解发生了什么