Unmarshall part of xml to an object [closed]

2019-02-07 21:55发布

问题:

I am trying to un-marshall an xml, which is turning out to be nightmare with lot of issues. So I got an idea to unmarshall part of this xml to an object which is necessary for me.

Original xml: http://snipurl.com/24qkyi7

now what I need from this xml is: http://snipurl.com/24qkyyl

I have classes and other related info of both xmls.

If I manually give this data http://snipurl.com/24ql04x to unmarshall, i am getting StandardError object. But can i give original xml directly to get this object out of it.

ps: Using JAXB

Stack trace of original xml parsing: http://snipurl.com/24qtrnv Class file of original xml class which I am failing to unmarshall. No source control on this http://snipurl.com/24qttn8

StandardError class: http://snipurl.com/24rpdld Main xml class: http://snipurl.com/24rpdxu

XSD: http://snipurl.com/24rryfi

回答1:

I would parser the XML using a StAX XMLStreamReader, and advance the XMLStreamReader to the element that you wish to unmarshal. Then I would have JAXB unmarshal the XMLStreamReader. Something like the following:

Demo

package bgc.objects.rosy.standarderror.v3;

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 {
        XMLInputFactory xif = XMLInputFactory.newFactory();
        StreamSource xml = new StreamSource("src/bgc/objects/rosy/standarderror/v3/input.xml");
        XMLStreamReader xsr = xif.createXMLStreamReader(xml);
        while(xsr.hasNext()) {
            if(xsr.isStartElement() && xsr.getLocalName().equals("StandardError")) {
                break;
            }
            xsr.next();
        }
        System.out.println(xsr.getLocalName());

        JAXBContext jc = JAXBContext.newInstance(StandardError.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        JAXBElement<StandardError> jb = unmarshaller.unmarshal(xsr, StandardError.class);
        StandardError response = jb.getValue();
        System.out.println(response);

        xsr.close();

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(jb, System.out);
    }

}

StandardError

Below is the StandardError class

package bgc.objects.rosy.standarderror.v3;

//Compiled from StandardError.java (version 1.5 : 49.0, super bit)
@javax.xml.bind.annotation.XmlAccessorType(value = javax.xml.bind.annotation.XmlAccessType.FIELD)
@javax.xml.bind.annotation.XmlType(name = "", propOrder = { "code", "category",
        "severity", "description", "environment", "correlationId" })
@javax.xml.bind.annotation.XmlRootElement(name = "StandardError")
public class StandardError {

    // Field descriptor #15 J
    protected long code;

    // Field descriptor #17 Ljava/lang/String;
    @javax.xml.bind.annotation.XmlElement(required = true)
    protected java.lang.String category;

    // Field descriptor #17 Ljava/lang/String;
    @javax.xml.bind.annotation.XmlElement(required = true)
    protected java.lang.String severity;

    // Field descriptor #24 Ljava/util/List;
    // Signature: Ljava/util/List<Ljava/lang/String;>;
    @javax.xml.bind.annotation.XmlElement(required = true)
    protected java.util.List description;

    // Field descriptor #17 Ljava/lang/String;
    @javax.xml.bind.annotation.XmlElement(required = true)
    protected java.lang.String environment;

    // Field descriptor #17 Ljava/lang/String;
    @javax.xml.bind.annotation.XmlElement(required = true)
    protected java.lang.String correlationId;

    // Field descriptor #17 Ljava/lang/String;
    @javax.xml.bind.annotation.XmlAttribute
    protected java.lang.String version;

}

package-info

I will use the @XmlSchema annotation on a package-info class to specify the namespace qualification for the classes in the bgc.objects.rosy.standarderror.v3 package.

@XmlSchema(namespace="urn:v3.standarderror.vss.objects.bgc", elementFormDefault=XmlNsForm.QUALIFIED)
package bgc.objects.rosy.standarderror.v3;

import javax.xml.bind.annotation.*;

Output

Below is the output from running the demo code:

StandardError
bgc.objects.rosy.standarderror.v3.StandardError@31884174
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<StandardError xmlns="urn:v3.standarderror.vss.objects.bgc">
    <code>209526</code>
    <category>TECHNICAL</category>
    <severity>ERROR</severity>
    <description xmlns:ns10="urn:v3.standarderror.vss.objects.bgc">APC operation AUDIT on position L02LAB00075:1-1-1-5
                returned an error : APC audit operation failed Caused by:
                com.alcatel.ni.commands.framework.model.UnsupportedDslamException:
                unsupported.dslam.message Caused by: Unsupported DSLAM. Internal
                rollback of failed action : success.</description>
    <environment>PRO</environment>
    <correlationId></correlationId>
</StandardError>

For More Information

  • http://blog.bdoughan.com/2012/08/handle-middle-of-xml-document-with-jaxb.html
  • http://blog.bdoughan.com/2010/08/jaxb-namespaces.html