【问题标题】:How to read/write multilevel xml file via Jaxb如何通过 Jaxb 读取/写入多级 xml 文件
【发布时间】:2014-06-16 15:31:47
【问题描述】:

我想通过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 &amp; Unmarshalling。这是项目要求。据我所知,在jaxb 我有一组课程。我必须创建一些方法,以便我可以通过 java 程序执行此操作。

请帮助我。我会感谢您的建议和回答。

【问题讨论】:

  • Jaxb 在后台使用了一个解析器,所以你已经隐含地使用了一个。你都尝试了些什么?你在哪里卡住了?
  • 我没有太多关于 Jaxb 的命令。请给你的电子邮件ID。我会把我的代码发给你。您可以修改并再次发送给我。我会感谢你的帮助。
  • 不做作业。 XML 真的需要这样吗?有一个包含零件的零件?还是更像是一个partlist?
  • 这是一个收费特定的数据。例如,发动机有气缸、活塞、螺钉、螺栓等。因此发动机将被视为父零件和活塞、气缸……所有将被视为子零件。气缸还有齿轮轴、轴杆等子零件。所以我必须以xml的形式提取数据,以显示它们之间的关系。
  • 那么你的根部分元素也需要有限定元素!

标签: java xml xslt jaxb xsd


【解决方案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 注释来执行此操作。

【讨论】:

    【解决方案2】:

    我认为您的 XML 中存在复制错误。您的根元素是&lt;partlist&gt;,或者它缺少元素 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 的战略性使用。这应该可以解决问题

    【讨论】:

    • 您创建了 XML 模式,但是您没有从中生成类模型,而是手动构建了一个?下面这篇文章将帮助你摆脱@XmlTransient注解。
    • 是的,我玩弄了注释来刷新我的记忆,事情是如何工作的。只有当人们知道它为您节省了哪些工作时,自动化才能得到赞赏。发现你的博客很有启发性。我知道访问类型。
    【解决方案3】:

    如果您的 xml 有 xsd,您甚至不需要手动创建 Java 对象。看看这个—— How to generate JAXB classes from XSD?。 编组和解组 - 试试http://www.mkyong.com/java/jaxb-hello-world-example/

    您应该真正尝试一些事情,然后在遇到困难时提出问题。这将使响应非常针对问题。

    【讨论】:

    • 是的,我从 xsd 生成了 java 类。但是对于多级 xml,我没有格式化 xsd。这个我必须手动创建。
    • @GopalSingh - 见Recursive XSD 的想法。
    猜你喜欢
    • 1970-01-01
    • 2021-06-07
    • 2014-11-19
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    • 1970-01-01
    • 2014-03-12
    相关资源
    最近更新 更多