【发布时间】:2018-03-20 03:18:18
【问题描述】:
我需要解析一些我拥有 XSD 的 XML 内容。一般来说,这是直截了当的。但是,在一种特殊情况下,XML 有时包含 XML 名称空间,有时不包含。此外,要求 XML 名称空间并不实际,因为提供的 XML 来自多个来源。所以我一直在努力寻找解决这个问题的方法。
如前所述,我有 XML 的 XSD,并且我使用 XJC(来自 JAXB)从 XSD 生成相应的 XML 实体类。
包含命名空间的 XML 示例:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://www.w3.org/namespace/">
<foo id="123>
<bar>value</bar>
</foo>
</root>
不包括命名空间的示例 XML:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<foo id="123>
<bar>value</bar>
</foo>
</root>
如您所见,XML 内容在结构上是相同的 - 唯一的区别是 root 实体上的 xmlxs 属性。
我的代码如下:
URI uri = <URI of XML file>
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
Node node = builder.parse(uri.toString()); // Parsing succeeds, ie. the XML is valid.
JAXBContext context = JAXBContext.newInstance("com.example.xml");
Unmarshaller parser = context.createUnmarshaller();
// Next line succeeds or fails, depending on presence of namespace
Object object = parser.unmarshal(node);
XML 总是被成功解析为Node。如果xmlns 属性出现在XML 中,那么整个过程正常完成并且我收到com.example.xml.Root 类的实例(使用XJC 生成)。从那里我可以访问Foo 和Bar 对象。
如果xmlns 属性不存在,则解组失败并出现以下异常:
javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"root").
Expected elements are <{http://www.w3.org/namespace/}root>,
<{http://www.w3.org/namespace/}foo>,
<{http://www.w3.org/namespace/}bar>
我尝试了unmarmshalling by declared type,但成功有限。具体来说,解组没有错误地完成。但是,生成的 Root 类不包含任何 Foo 或 Bar 对象。
此代码涉及将最后一行更改为:
Object object = parser.unmarshal(node, Root.class);
我尝试将“命名空间感知”标志设置为false 进行解组,但失败并出现错误。
如果node 没有命名空间,我已经考虑在解组之前添加一个命名空间。但是 API 似乎不允许这样做。
我的另一个想法是有两组生成的类,每种情况一个(即命名空间,没有命名空间)。然而,这似乎太过分了。
所以我被卡住了?有什么建议?还是我试图做的事情是不可能的?
【问题讨论】:
标签: java xsd xml-parsing jaxb