XML的结构如下:
<xml .../>
<dataFile>
<header>
<name>firstname</name>
<name>surname</name>
</header>
<content>
<row>
<column>seb</column>
<column>teb</column>
</row>
<row>
<column>leb</column>
<column>pleb</column>
</row>
</content>
</dataFile>
该架构牵强,请不要被触发。
现在这是我的模型,它由4个类组成,
DataFile.class:
@XmlRootElement
public class DataFile {
private Header header;
private Content content;
public DataFile() {
this.header = new Header();
this.content = new Content();
}
public DataFile(Header header, Content content) {
this.header = header;
this.content = content;
}
@XmlElement
public Header getHeader() {
return header;
}
public void setHeader(Header header) {
this.header = header;
}
@XmlElement
public Content getContent() {
return content;
}
public void setContent(Content content) {
this.content = content;
}
}
Header.class
public class Header {
private List<String> name;
public Header() {
this.name = new ArrayList<>();
}
public Header(List<String> name) {
this.name = name;
}
public List<String> getName() {
return name;
}
public void setName(List<String> name) {
this.name = name;
}
}
Content.class
public class Content {
private List<Row> row;
public Content() {
this.row = new ArrayList<>();
}
public Content(List<Row> rows) {
this.row = rows;
}
public List<Row> getRow() {
return row;
}
public void setRow(List<Row> row) {
this.row = row;
}
}
Row.class
public class Row {
private List<String> column;
public Row() {
}
public Row(List<String> column) {
this.column = column;
}
public List<String> getColumn() {
return column;
}
public void setColumn(List<String> column) {
this.column = column;
}
}
这是我用来将XML文件解组到DataFile模型的方法:
public DataFile JaxBValidate(File file) throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(DataFile.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
return (DataFile) jaxbUnmarshaller.unmarshal(file);
}
我遇到的问题是,如果我有超过1个标签,JAXB总是会选择最后一个标签,如果头超过1个,我希望它在这里抛出异常。
我环顾四周,没有发现任何问题,也没有查看DataFile模型的注释,也没有发现任何东西指定我只想拥有1个标头标记。
我找到了一种使用XPath进行解析而不是使用JAXB的解决方案,但是我很好奇是否有人对此有所了解。
答案 0 :(得分:1)
您需要定义设置了字段数的XSD
文件,并将其附加到JAXB
解组器中:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="dataFile" type="dataFileType"/>
<xs:complexType name="headerType">
<xs:sequence>
<xs:element name="name" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="rowType">
<xs:sequence>
<xs:element name="column" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="contentType">
<xs:sequence>
<xs:element type="rowType" name="row" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="dataFileType">
<xs:sequence>
<xs:element type="headerType" name="header" maxOccurs="1"/>
<xs:element type="contentType" name="content" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
这是我们可以使用架构解集XML
的方式:
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class JaxbApp {
public static void main(String[] args) throws Exception {
File xmlFile = new File("./resource/test.xml").getAbsoluteFile();
File xsdFile = new File("./resource/test.xsd").getAbsoluteFile();
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(xsdFile);
JAXBContext jaxbContext = JAXBContext.newInstance(DataFile.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
unmarshaller.setSchema(schema);
Object root = unmarshaller.unmarshal(xmlFile);
System.out.println(root);
}
}
对于低于XML
的有效载荷:
<?xml version="1.0" encoding="UTF-8"?>
<dataFile>
<header>
<name>firstname</name>
<name>surname</name>
</header>
<header>
<name>firstname1</name>
<name>surname1</name>
</header>
<content>
<row>
<column>seb</column>
<column>teb</column>
</row>
<row>
<column>leb</column>
<column>pleb</column>
</row>
</content>
</dataFile>
引发异常:
Exception in thread "main" javax.xml.bind.UnmarshalException
- with linked exception:
[org.xml.sax.SAXParseException; systemId: file:./resource/test.xml; lineNumber: 7; columnNumber: 13; cvc-complex-type.2.4.a: Invalid content was found starting with element 'header'. One of '{content}' is expected.]
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:335)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:563)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:249)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
另请参阅:
答案 1 :(得分:0)
尝试一下,
DataFile.java
@XmlRootElement
public class DataFile {
private List<Header> header;
private List<Content> content;
@XmlElement
public List<Header> getHeader() {
return header;
}
public void setHeader(List<Header> header) {
this.header = header;
}
@XmlElement
public List<Content> getContent() {
return content;
}
public void setContent(List<Content> content) {
this.content = content;
}
}
Header.java
@XmlRootElement
public class Header {
private List<String> name;
@XmlElement
public List<String> getName() {
return name;
}
public void setName(List<String> name) {
this.name = name;
}
}
Content.java
@XmlRootElement
public class Content {
private List<Row> row;
@XmlElement
public List<Row> getRow() {
return row;
}
public void setRow(List<Row> row) {
this.row = row;
}
}
Row.java
@XmlRootElement
public class Row {
private List<String> column;
@XmlElement
public List<String> getColumn() {
return column;
}
public void setColumn(List<String> column) {
this.column = column;
}
}
用于DataFile解组
File file = new File("xmlFile.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(DataFile.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
DataFile dataFile = (DataFile) jaxbUnmarshaller.unmarshal(file);
用于获取给定xml文件中<header>
个标签的数量
int noOfHeader = dataFile.getHeader().size();