2

我有一个由 JAXB 生成的 XML。请参阅下面的 XML 文件

<config>
 <instance>
      <hostName>192.168.2.98</hostName>
      <port>444</port>
 </instance>
 <instance>
      <hostName>192.168.3.2</hostName>
      <port>3333</port>
 </instance>
 <instance>
      <hostName>192.168.1.168</hostName>
      <port>168</port>
 </instance>
</config>

现在,我的计划是按照以下步骤修改 XML:

  1. 第一个“实例”元素端口值
  2. 第二个“实例”元素主机名值
  3. 第三个“实例”元素端口和主机名值

结果应该是这样的

<config>
 <instance>
      <hostName>192.168.2.98</hostName>
      <port>555</port>
 </instance>
 <instance>
      <hostName>192.168.3.140</hostName>
      <port>3333</port>
 </instance>
 <instance>
      <hostName>192.168.1.130</hostName>
      <port>8181</port>
 </instance>
</config>

如何使用 JAXB 做到这一点?我应该将其 umnmarshall 到JAXBElement并将其传递给Binder吗?

仅供参考,我使用 HTML 表单通过JAX-RS修改 XML 文件。下面的资源发布方法仅适用于创建新实例,但不适用于修改/更新元素值

@POST
@Path("/modhost")
@Consumes({ MediaType.APPLICATION_FORM_URLENCODED,
        MediaType.APPLICATION_JSON })
@Produces(MediaType.APPLICATION_JSON)
public void modInstance(@FormParam("host") String hostX,
        @FormParam("port") String portX) {


    this.host = hostX;
    this.port = portX;




    try {

        String env = System.getenv("APP_HOME");

        String tesfile = env+"/tes2.xml";
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        File filex = new File(tesfile);
        Document document = db.parse(filex);

        JAXBContext jc = JAXBContext.newInstance(Config.class);

        Binder<Node> binder = jc.createBinder();
        Config config= (Config) binder.unmarshal(document);
        Unmarshaller unmarshaller = jc.createUnmarshaller();


        List<Instance> instList = new ArrayList<Instance>();
        Instance inst = new Instance();
        inst.setHostName(host);
        inst.setPort(port);

        instList.add(inst);

        config.getInstance().addAll(instList);
        binder.updateXML(config);

        TransformerFactory tf = TransformerFactory.newInstance();
        StreamResult result = new StreamResult(filex);
        Transformer t = tf.newTransformer();
        t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "5");
        t.setOutputProperty(OutputKeys.INDENT, "yes");
        t.transform(new DOMSource(document), result);
    } catch (TransformerConfigurationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ParserConfigurationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (JAXBException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (TransformerFactoryConfigurationError e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (TransformerException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

这里是 JAXB 类ConfigInstance

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = { "instances"})
@XmlRootElement(name = "config")
public class Config{

    @XmlElement(required = true)
    protected List<Instance> instance;


    public List<Instance> getInstance() {
      if (instance == null) {
          instance = new ArrayList<Instance>();
      }
    return this.instance;
}



@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = { "hostName", "port"})
@XmlRootElement(name = "instance")
public class Instances {

   @XmlElement(required = true)
   protected String hostName;
   @XmlElement(required = true)
   protected String port;

   public String getHostName() {
      return hostName;
   }


    public void setHostName(String value) {
       this.hostName = value;
   }


    public String getPort() {
      return port;
   }


   public void setPort(String value) {
      this.port = value;
   }

}
4

1 回答 1

4

我认为这应该有效

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
class Config {
    @XmlElement(name="instance", required = true)
    protected List<Instance> instances;

    public List<Instance> getInstances() {
        return instances;
    }
}

@XmlAccessorType(XmlAccessType.FIELD)
class Instance {
    protected String hostName;
    protected String port;

    public String getHostName() {
        return hostName;
    }

    public void setHostName(String value) {
        this.hostName = value;
    }

    public String getPort() {
        return port;
    }

    public void setPort(String value) {
        this.port = value;
    }
}


public static void main(String[] args) throws Exception {
    JAXBContext jc = JAXBContext.newInstance(Config.class);
    Config config = (Config)jc.createUnmarshaller().unmarshal(new File("1.xml"));
    List<Instances> list = config.getInstances();
    list.get(0).setPort(555);
    list.get(1).setHostName("192.168.3.140");
    list.get(2).setPort(168);
    list.get(2).setHostName("192.168.1.168");

    Marshaller m = jc.createMarshaller();
    m.marshal(config,  filex);
于 2013-03-20T09:05:46.713 回答