Java 使用带@XmlPath的通配符解析类似表示
我有一个很深的XML结构,有很多无意义的包装,我正在映射到一个Java类。有几个不同的文件,其中的内容和结构略有不同。由于我希望能够将生成的类转换为易于比较的类(例如,每个表示都包含一个名称),我想知道是否可以为Java 使用带@XmlPath的通配符解析类似表示,java,xml,jaxb,moxy,Java,Xml,Jaxb,Moxy,我有一个很深的XML结构,有很多无意义的包装,我正在映射到一个Java类。有几个不同的文件,其中的内容和结构略有不同。由于我希望能够将生成的类转换为易于比较的类(例如,每个表示都包含一个名称),我想知道是否可以为@XmlPath指定通配符 继承是我(部分)解决问题的第一个想法,但由于结构顶部有一个不同的包装元素,我不确定如何解决这个问题 示例XML结构 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <s:root
@XmlPath
指定通配符
继承是我(部分)解决问题的第一个想法,但由于结构顶部有一个不同的包装元素,我不确定如何解决这个问题
示例XML结构
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<s:root xsi:schemaLocation="http://www.example.eu/test ResourceSchema.xsd" xmlns:s="http://www.example.eu/test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:resource|s:data|s:container|s:stackoverflow>
<s:information>
<s:date>2013-07-04</s:date>
<s:name>This example does not work</s:name>
</s:information>
<s:elements>
<s:refobj>
<s:id>1</s:id>
<s:source>First Source</s:source>
</s:refobj>
<s:refobj>
<s:id>2</s:id>
<s:source>Second Source</s:source>
</s:refobj>
<s:refobj>
<s:id>5</s:id>
<s:source>Fifth Source</s:source>
</s:refobj>
</s:elements>
</s:resource|s:data|s:container|s:stackoverflow>
</s:root>
2013-07-04
这个例子不起作用
1.
第一来源
2.
第二来源
5.
第五来源
XML中的第二个元素显然无效,尽管这是结构不同的地方,可以包含几乎所有内容。然而,第三级元素information
确实存在于每个结构中,它甚至包含关于XML中表示的元素类型的信息
一个快速的解决方案是为每个可能的元素创建一个类,然后尝试/捕获所有元素,直到其中一个成功,尽管这似乎是一个可怕的解决方案
解决这样一个与XML相关的问题的正确方法是什么?我无法更改结构,也无法访问模式来告诉我哪些元素具有多个名称。MOXy目前不支持
@XmlPath
中的通配符,但下面是一种使用StreamReaderDelegate
实现这一点的方法
域模型
根目录
套餐信息
演示代码
演示
input.xml
通过以下输入,StreamReaderDelegate
将导致resource
元素报告为stackoverflow
,匹配项正在映射
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<s:root xsi:schemaLocation="http://www.example.eu/test ResourceSchema.xsd" xmlns:s="http://www.example.eu/test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:resource>
<s:information>
<s:date>2013-07-04</s:date>
<s:name>This example does not work</s:name>
</s:information>
</s:resource>
</s:root>
2013-07-04
这个例子不起作用
输出
输出将匹配域模型中的映射
<?xml version="1.0" encoding="UTF-8"?>
<s:root xsi:schemaLocation="http://www.example.eu/test ResourceSchema.xsd" xmlns:s="http://www.example.eu/test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:stackoverflow>
<s:information>
<s:date>2013-07-04</s:date>
<s:name>This example does not work</s:name>
</s:information>
</s:stackoverflow>
</s:root>
2013-07-04
这个例子不起作用
了解更多信息
package forum17527941;
import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.stream.util.StreamReaderDelegate;
import javax.xml.transform.stream.StreamSource;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
XMLInputFactory xif = XMLInputFactory.newFactory();
StreamSource xml = new StreamSource("src/forum17527941/input.xml");
XMLStreamReader xsr = xif.createXMLStreamReader(xml);
xsr = new StreamReaderDelegate(xsr) {
@Override
public String getLocalName() {
String localName = super.getLocalName();
if("resource".equals(localName) || "data".equals(localName) || "container".equals(localName)) {
return "stackoverflow";
}
return localName;
}
};
Unmarshaller unmarshaller = jc.createUnmarshaller();
Root root = (Root) unmarshaller.unmarshal(xsr);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.example.eu/test ResourceSchema.xsd");
marshaller.marshal(root, System.out);
}
}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<s:root xsi:schemaLocation="http://www.example.eu/test ResourceSchema.xsd" xmlns:s="http://www.example.eu/test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:resource>
<s:information>
<s:date>2013-07-04</s:date>
<s:name>This example does not work</s:name>
</s:information>
</s:resource>
</s:root>
<?xml version="1.0" encoding="UTF-8"?>
<s:root xsi:schemaLocation="http://www.example.eu/test ResourceSchema.xsd" xmlns:s="http://www.example.eu/test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:stackoverflow>
<s:information>
<s:date>2013-07-04</s:date>
<s:name>This example does not work</s:name>
</s:information>
</s:stackoverflow>
</s:root>