如何通过Jaxb读/写多级xml文件

时间:2014-04-30 10:41:11

标签: java xml xslt jaxb xsd

我想通过Jaxb读取或写入多级Xml文件(不能使用xml解析器)。 例如,一部分(被视为父部分)具有许多子部分。那个孩子也有孩子的部分。  所以结构就像我手动创建的那样。

  

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<part xmlns="http://www.serus.com">
    <part>
        <Part_Number>n0</Part_Number>
        <Part_Version>revision0</Part_Version>
        <Part_Type>p0</Part_Type>
        <Status>current0</Status>
    </part>
    <part>

        <Part_Number>n1</Part_Number>
        <Part_Version>revision1</Part_Version>
        <Part_Type>p1</Part_Type>
        <Status>current1</Status>

         <part>
            <Part_Number>n2</Part_Number>
            <Part_Version>revision2</Part_Version>
            <Part_Type>p2</Part_Type>
            <Status>current2</Status>

             <part>
                <Part_Number>n3</Part_Number>
                <Part_Version>revision3</Part_Version>
                <Part_Type>p3</Part_Type>
                <Status>current3</Status>
            </part>

        </part>


    <part>
        <Part_Number>n3</Part_Number>
        <Part_Version>revision3</Part_Version>
        <Part_Type>p3</Part_Type>
        <Status>current3</Status>
    </part>

    </part>

    <part>
        <Part_Number>n4</Part_Number>
        <Part_Version>revision4</Part_Version>
        <Part_Type>p4</Part_Type>
        <Status>current4</Status>
    </part>
</part>

我必须为这类数据执行marshalling & Unmarshalling。这是项目要求。据我所知,在jaxb我有一组课程。我必须创建一些方法,以便我可以通过java程序执行此操作。

请帮帮我。我会为你的建议而努力。答案。

  

3 个答案:

答案 0 :(得分:1)

您的Java模型将如下所示。一个Part类,它包含其他Part个实例的列表以及其他一些数据。

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Part {

    @XmlElement(name="Part_Number");
    private String partNo;

    @XmlElement(name="part")
    private List<Part> parts;

}

您可以从我的博客中找到以下文章:

命名空间限定

由于您的XML文档是名称空间限定的,因此您需要将其纳入映射元数据中。我建议使用包级别@XmlSchema注释执行此操作。

答案 1 :(得分:0)

我认为您的XML中存在复制错误。您的根元素是<partlist>,或者它缺少元素Part_Number,Part_Version,Part_Type和Status(这是有意义的)。所以你的架构看起来像这样:

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.serus.com" xmlns:ns1="http://www.serus.com">
      <xs:element name="part">
        <xs:complexType> 
          <xs:sequence minOccurs="1" maxOccurs="1">
            <xs:element ref="ns1:Part_Number"/>
            <xs:element ref="ns1:Part_Type"/>
            <xs:element ref="ns1:Part_Version"/>
            <xs:element ref="ns1:Status"/>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
              <xs:element ref="ns1:part"/>
            </xs:choice>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="Part_Number" type="xs:NCName"/>
      <xs:element name="Part_Type" type="xs:NCName"/>
      <xs:element name="Part_Version" type="xs:NCName"/>
      <xs:element name="Status" type="xs:NCName"/>
    </xs:schema>

然后一个类会有这种格式:

    import java.io.ByteArrayOutputStream;
    import java.io.InputStream;
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.Collection;

    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.JAXBException;
    import javax.xml.bind.Marshaller;
    import javax.xml.bind.Unmarshaller;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    import javax.xml.bind.annotation.XmlTransient;

    @XmlRootElement(name = "part")
    public class Part implements Serializable {

        public static Part fromXML(InputStream in) throws Exception {
            JAXBContext context = JAXBContext.newInstance(Part.class);
            Unmarshaller um = context.createUnmarshaller();
            return (Part) um.unmarshal(in);
        }

        private static final long   serialVersionUID    = 1L;
        @XmlElement(name = "Part_Number")
        private String              partNumber;
        @XmlElement(name = "Part_Type")
        private String              partType;
        @XmlElement(name = "Part_Version")
        private String              partVersion;
        @XmlElement(name = "Status")
        private String              status;
        @XmlElement(name = "part")
        private Collection<Part>    subParts            = null;

        public static void main(String args[]) throws JAXBException {
            Part mainPart = new Part("1m", "mType", "version 1", "draft");
            Part level1 = new Part("l1", "l1Type", "version 11", "new");
            level1.addPart(new Part("l2", "l2Type", "version 1", "new"));
            level1.addPart(new Part("l2-2", "l2Type", "version 1", "new"));
            mainPart.addPart(level1);
            System.out.println(mainPart.toXML());
        }

        public Part() {
            // No action here
        }

        public Part(String no, String type, String ver, String stat) {
            this.partNumber = no;
            this.partType = type;
            this.partVersion = ver;
            this.status = stat;
        }

        @XmlTransient
        public String getPartNumber() {
            return this.partNumber;
        }

        public void setPartNumber(String partNumber) {
            this.partNumber = partNumber;
        }

        @XmlTransient
        public String getPartType() {
            return this.partType;
        }

        public void setPartType(String partType) {
            this.partType = partType;
        }

        @XmlTransient
        public String getPartVersion() {
            return this.partVersion;
        }

        public void setPartVersion(String partVersion) {
            this.partVersion = partVersion;
        }

        @XmlTransient
        public String getStatus() {
            return this.status;
        }

        public void setStatus(String status) {
            this.status = status;
        }

        @XmlTransient
        public Collection<Part> getSubparts() {
            return this.subParts;
        }

        public void setSubparts(Collection<Part> subparts) {
            this.subParts = subparts;
        }

        public void addPart(Part part) {
            if (this.subParts == null) {
                this.subParts = new ArrayList<Part>();
            }
            this.subParts.add(part);
        }

        public void addParts(Collection<Part> parts) {
            if (this.subParts == null) {
                this.subParts = new ArrayList<Part>();
            }

            this.subParts.addAll(parts);
        }

        public String toXML() throws JAXBException {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            JAXBContext context = JAXBContext.newInstance(Part.class);
            Marshaller m = context.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            m.marshal(this, out);
            return out.toString();
        }

    }

这里的诀窍是战略性地使用@XmlElement(name = "part")@XmlTransient。那应该是诀窍

答案 2 :(得分:-1)

如果你的xml有xsd,你甚至不需要手动创建Java obejcts。检查一下 - How to generate JAXB classes from XSD?。 编组和解组 - 试用http://www.mkyong.com/java/jaxb-hello-world-example/

你应该尝试一些事情然后在某些时候陷入困境时提出问题。这将使回答非常具体地解决问题。