bez*_*max 5 java xml dom xsitype
我有2个Document对象,文档包含类似的XML.例如:
<tt:root xmlns:tt="http://myurl.com/">
<tt:child/>
<tt:child/>
</tt:root>
Run Code Online (Sandbox Code Playgroud)
而另一个:
<ns1:root xmlns:ns1="http://myurl.com/" xmlns:ns2="http://myotherurl.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:child/>
<ns1:child xsi:type="ns2:SomeType"/>
</ns1:root>
Run Code Online (Sandbox Code Playgroud)
我需要将它们合并到1个带有1个根元素和4个子元素的文档中.问题是,如果我使用document.importNode函数进行合并,它可以在任何地方正确处理命名空间但是xsi:type元素.所以我得到的结果是:
<tt:root xmlns:tt="http://myurl.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<tt:child/>
<tt:child/>
<ns1:child xmlns:ns1="http://myurl.com/"/>
<ns1:child xmlns:ns1="http://myurl.com/" xsi:type="ns2:SomeType"/>
</tt:root>
Run Code Online (Sandbox Code Playgroud)
如您所见,ns2用于xsi:type但未在任何地方定义.有没有自动解决这个问题的方法?
谢谢.
添加:
如果使用默认的java DOM库无法完成此任务,可能还有一些其他库可用于完成我的任务?
单行XQuery就可以完成这项工作:构造一个名为上下文根元素的新节点,然后将其子节点与其他文档中的子节点一起导入:
declare variable $other external; element {node-name(*)} {*/*, $other/*/*}
Run Code Online (Sandbox Code Playgroud)
尽管在 XQuery 中您无法完全控制名称空间节点(至少在 XQuery 1.0 中),但它有一个copy-namespaces模式设置,可用于要求保持名称空间上下文完整,以防实现默认情况下保留它。
如果 XQuery 是一个可行的选择,那么saxon9he.jar可能就是您所追求的“神奇 xml 库”。
以下是使用s9api API公开一些上下文的示例代码:
import javax.xml.parsers.DocumentBuilderFactory;
import net.sf.saxon.s9api.*;
import org.w3c.dom.Document;
...
Document merge(Document context, Document other) throws Exception
{
Processor processor = new Processor(false);
XQueryExecutable executable = processor.newXQueryCompiler().compile(
"declare variable $other external; element {node-name(*)} {*/*, $other/*/*}");
XQueryEvaluator evaluator = executable.load();
DocumentBuilder db = processor.newDocumentBuilder();
evaluator.setContextItem(db.wrap(context));
evaluator.setExternalVariable(new QName("other"), db.wrap(other));
Document doc =
DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
processor.writeXdmValue(evaluator.evaluate(), new DOMDestination(doc));
return doc;
}
Run Code Online (Sandbox Code Playgroud)