gpt4 book ai didi

java - 如何使用不同的命名空间解码 xml

转载 作者:行者123 更新时间:2023-11-30 08:04:49 25 4
gpt4 key购买 nike

我使用 JAXB 2.0 并希望解码 xml 并获取验证错误。例如,如果缺少某些元素或属性。这是我要解析的 xml:

<?xml version="1.1" encoding="utf-8"?>
<package version="2.0" xmlns="http://www.idpf.org/2007/opf">
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
<dc:title>Title</dc:title>
</metadata>
</package>

我的模型类:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "package")
public class Package {
@XmlElement(required = true)
public Metadata metadata;

@XmlAttribute(name = "version", required = true)
public String version;
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "metadata")
public class Metadata {

@XmlElement(namespace = "http://purl.org/dc/elements/1.1/", required = true)
public String title;
}

package-info.java 还有一个注释:

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.idpf.org/2007/opf", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)

以及解码代码:

    JAXBContext jc = JAXBContext.newInstance(Package.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();

final List<ByteArrayOutputStream> outs = new ArrayList<>();
jc.generateSchema(new SchemaOutputResolver(){
@Override
public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
outs.add(out);
StreamResult streamResult = new StreamResult(out);
streamResult.setSystemId("");
return streamResult;
}});
StreamSource[] sources = new StreamSource[outs.size()];
for (int i=0; i<outs.size(); i++) {
ByteArrayOutputStream out = outs.get(i);
System.out.append(new String(out.toByteArray()));
sources[i] = new StreamSource(new ByteArrayInputStream(out.toByteArray()),"");
}
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(sources);
unmarshaller.setSchema(schema);

unmarshaller.setEventHandler(event -> {
System.out.append(event.toString());
return true;
});
Opf file = (Opf) unmarshaller.unmarshal(opfFile);

它生成该架构:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema elementFormDefault="qualified" version="1.0" targetNamespace="http://www.idpf.org/2007/opf" xmlns:tns="http://www.idpf.org/2007/opf" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://purl.org/dc/elements/1.1/">
<xs:import namespace="http://purl.org/dc/elements/1.1/"/>
<xs:element name="metadata" type="tns:metadata"/>
<xs:element name="package" type="tns:package"/>
<xs:complexType name="package">
<xs:sequence>
<xs:element ref="tns:metadata"/>
</xs:sequence>
<xs:attribute name="version" type="xs:anySimpleType" use="required"/>
</xs:complexType>
<xs:complexType name="metadata">
<xs:sequence>
<xs:element ref="ns1:title"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" targetNamespace="http://purl.org/dc/elements/1.1/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="title" type="xs:string"/>
</xs:schema>

在解码过程中,它会抛出错误:org.xml.sax.SAXParseException:src-resolve:无法将名称“ns1:title”解析为(n)“元素声明”组件。

我应该如何注释我的类来解析这个 xml 文件?

最佳答案

你必须亲自动手使用资源解析器;下面是工作代码:

    JAXBContext jc = JAXBContext.newInstance(Package.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();

final Map<String, ByteArrayOutputStream> outs = new HashMap<String, ByteArrayOutputStream>();

jc.generateSchema(new SchemaOutputResolver(){
@Override
public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException{
ByteArrayOutputStream out = new ByteArrayOutputStream();
outs.put(suggestedFileName, out);
StreamResult streamResult = new StreamResult(out);
streamResult.setSystemId(suggestedFileName);
return streamResult;
}});
StreamSource[] sources = new StreamSource[outs.size()];
int i = 0;
for (Map.Entry<String, ByteArrayOutputStream> entry: outs.entrySet()) {
System.out.append(new String(entry.getValue().toByteArray()));
sources[i++] = new StreamSource(new ByteArrayInputStream(entry.getValue().toByteArray()), entry.getKey());
}
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
sf.setResourceResolver(new LSResourceResolver(){
@Override
public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI){
ByteArrayOutputStream bout = outs.get(systemId);
if(bout!=null){
return new DOMInputImpl(publicId, systemId, baseURI, new ByteArrayInputStream(bout.toByteArray()), null);
}else
return null;
}
});
Schema schema = sf.newSchema(sources);
unmarshaller.setSchema(schema);
unmarshaller.setEventHandler(new ValidationEventHandler(){
@Override
public boolean handleEvent(ValidationEvent event){
System.out.append(event.toString());
return true;
}
});

Object obj = unmarshaller.unmarshal(new File("package.xml"));

关于java - 如何使用不同的命名空间解码 xml,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31274116/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com