根据Apache Xerces 关于 XInclude 的文档(Java内部用于XML解析)
对于简写指针和 element() XPointers,当前仅支持 DTD 确定的 ID。
这意味着您需要将如下所示的标记声明放入您的target.xml
文件(告诉 XML 解析器id
属性被视为属性ID
语义,并告诉 XIninclude 将“裸”XPointers 解释为 ID 引用):
<!DOCTYPE foo [
<!ATTLIST bar id ID #IMPLIED>
]>
<foo>
<bar id="ABCD"/>
</foo>
如果您现在使用以下文档作为源 XML(您已将其命名为result.xml
在您的示例代码中,我对其进行了编辑以包含 XInclude 命名空间 URI 绑定xi
)
<lorem xmlns:xi="http://www.w3.org/2001/XInclude">
<ipsum>
<xi:include href="target.xml" xpointer="ABCD"/>
</ipsum>
</lorem>
那么 Xerces 将建立一个Document
其中 XInclude 处理已根据需要执行(我已将示例数据放入target.xml
文件与该文件位于同一目录中result.xml
file):
<lorem xmlns:xi="http://www.w3.org/2001/XInclude">
<ipsum>
<bar id="ABCD" xml:base="target.xml"/>
</ipsum>
</lorem>
我用来生成文档的 Java 代码是根据您的示例进行简化的,并且不包含第三方库:
import java.io.*;
import javax.xml.*;
import javax.xml.parsers.*;
import javax.xml.validation.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
import org.w3c.dom.*;
public class t {
public static void main(String[] args) {
try {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setXIncludeAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document itemDoc = builder.parse(new File("result.xml"));
System.out.println(serialize(itemDoc));
}
catch (Exception ex) {
ex.printStackTrace();
}
}
static String serialize(Document doc) throws Exception {
Transformer transformer =
TransformerFactory.newInstance().newTransformer();
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
return result.getWriter().toString();
}
}
鉴于您还使用 XML 模式验证,我还想指出 XInclude 与 XML 模式的潜在交互,例如。讨论于X包括架构/命名空间验证?,以及中讨论的潜在替代方案复制 XML 的某些部分而不重写它们 .