XML 注释 (JAXB) 解组和编组建议

XML annotations (JAXB) suggestions for unmarshalling and marshalling

我有一个样本XML如下图:

<?xml version="1.0" encoding="UTF-8"?>
<Education>
    <School name="ABC" location="Mangalore">
        <Student gender="M" housepincode="575020">
            <FirstName>VJ</FirstName>
            <LastName>K</LastName>
        </Student>
        <Student gender="M" housepincode="575002">
            <FirstName>S</FirstName>
            <LastName>K</LastName>
        </Student>
    </School>
</Education>

这已在 JAXB 的帮助下使用以下方法解组。 我有 class 教育、学校和学生。

Education.java

import lombok.Data;
@Data
@XmlRootElement(name = "Education")
public class Education {    
    public School School;
}

School.java

import lombok.Data;
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class School {   
    @XmlAttribute
    private String name;    
    @XmlAttribute
    private String location;    
    @XmlElement(name ="Student")
    private List<Student> Student;
}

Student.java

@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class Student {      
    @XmlAttribute
    private String gender;  
    @XmlAttribute
    private String housepincode;    
    @XmlElement(name = "FirstName")
    private String FirstName;
    @XmlElement(name = "LastName")
    private String LastName;
}

我对收到的输出有一些担忧。首先有一些警告。我相信这是因为我错过了一些应该存在的注释。请问这里有什么建议或指导吗?

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.sun.xml.bind.v2.runtime.reflect.opt.Injector (file:/C:/Users/R.Premsagar/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.0-b170127.1453/jaxb-runtime-2.3.0-b170127.1453.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int)
WARNING: Please consider reporting this to the maintainers of com.sun.xml.bind.v2.runtime.reflect.opt.Injector
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Education(School=School(name=ABC, location=Mangalore, Student=[Student(gender=M, housepincode=575020, FirstName=VJ, LastName=K), Student(gender=M, housepincode=575002, FirstName=S, LastName=K)]))

此外,输出的层次结构对我来说似乎不正确,例如:学校 = 学校标签? 我想将此输出打印到单独的 XML 以验证结果。 但是脚本失败

主程序:

List<Education> Entries = new ArrayList<Education>();
        try {
            File xmlFile = new File("Withattributes.xml");
            JAXBContext jaxbContext;
            jaxbContext = JAXBContext.newInstance(Education.class);                          
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();        
            Education entries = (Education) jaxbUnmarshaller.unmarshal(xmlFile);    
            Entries.add(entries); //storing objects in a list for later use
            
            
            //--------------------------------------------------------------
            JAXBContext jaxbContext_w = JAXBContext.newInstance(Education.class);           
            Marshaller jaxbMarshaller = jaxbContext_w.createMarshaller();
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            jaxbMarshaller.marshal(jaxbContext_w, System.out);
}
        catch (JAXBException e) 
        {
            e.printStackTrace();
        } catch (FactoryConfigurationError e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
}

我收到以下错误消息:

Neither the class com.sun.xml.bind.v2.runtime.JAXBContextImpl nor one of the associated superclasses is known to this context.
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:593)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:482)
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:328)
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:256)
    at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:110)
    at JaxbExample.main(JaxbExample.java:39)

请让我知道这里可以做什么..


更新:

如果 XML 更新为具有如下结构:

<?xml version="1.0" encoding="UTF-8"?>
<Education>
    <School name="ABC" location="Mangalore">
        <Student gender="M" housepincode="575020">
            <FirstName>VJ</FirstName>
            <LastName>K</LastName>
            <Hobbies>
                  <Hobby time = "M">Novels</Hobby>
                  <Hobby time = "A">Gaming</Hobby>
            </Hobbies>
        </Student>
    </School>
</Education>

现在 Student.java 的 class 将更改为

@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class Student {      
    @XmlAttribute
    private String gender;  
    @XmlAttribute
    private String housepincode;    
    @XmlElement(name = "FirstName")
    private String FirstName;
    @XmlElement(name = "LastName")
    private String LastName;
    @XmlElementWrapper(name ="Hobbies")
    @XmlElement(name="Hobby")
    private List<Hobby> Hobbies;
}

和Hobby.java

@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class Hobby{
    
    @XmlAttribute(name="Time")
    private String Time;
    
    @XmlElement
    private String Hobby;

}

通过此修改,我无法获得 Hobby 标签的值。我得到了这样的爱好和价值观列表:

            Hobbies>
                  <Hobby time = "M"/>
                  <Hobby time = "A"/>
            </Hobbies>

你能在这里纠正我吗?

第一期: 我不是 JAXB 方面的专家,所以我不太清楚什么会导致此处指定的警告,但我尝试按照代码进行操作,它似乎对我来说工作正常,没有任何警告。如果您想获得更多理解,那么最好的办法是搜索它并阅读文档以获取更多信息。但我的猜测是它是由于您的第二个问题而发生的。

此外,我正在使用 Moxy,它是 Eclipse-link 开发的 JAXB 的扩展。与简单的 JAXB

相比,它有许多额外的好处

第二期: 这一行有明显的错误:

jaxbMarshaller.marshal(jaxbContext_w, System.out);

为什么要提供 jaxbContext_w 作为输入。它应该是未编组的值。在您的情况下,它是 entries.

完整代码如下: 教育:

@Data
@XmlRootElement(name = "Education")
@XmlAccessorType(XmlAccessType.FIELD)
public class Education {
    public School School;
}

学校:

@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class School {
    @XmlAttribute
    private String name;

    @XmlAttribute
    private String location;

    @XmlElement
    private List<Student> Student;
}

学生:

@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class Student {
    @XmlAttribute
    private String gender;

    @XmlAttribute
    private String housepincode;

    @XmlElement
    private String FirstName;

    @XmlElement
    private String LastName;
}

主要:


public class Main {
    public static void main(String[] args) throws JAXBException, XMLStreamException {
        final InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("students.xml");
        final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
        final Unmarshaller unmarshaller = JAXBContext.newInstance(Education.class).createUnmarshaller();
        final Education education = unmarshaller.unmarshal(xmlStreamReader, Education.class).getValue();
        System.out.println(education.toString());

        Marshaller marshaller = JAXBContext.newInstance(Education.class).createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.marshal(education, System.out);
    }
}

输出(没有任何错误或警告):


Education(School=School(name=ABC, location=Mangalore, Student=[Student(gender=M, housepincode=575020, FirstName=VJ, LastName=K), Student(gender=M, housepincode=575002, FirstName=S, LastName=K)]))
<Education>
   <School name="ABC" location="Mangalore">
      <Student gender="M" housepincode="575020">
         <FirstName>VJ</FirstName>
         <LastName>K</LastName>
      </Student>
      <Student gender="M" housepincode="575002">
         <FirstName>S</FirstName>
         <LastName>K</LastName>
      </Student>
   </School>
</Education>