gpt4 book ai didi

java - 尝试将 XInclude 与 Java 结合使用并使用 xml :id 解析片段

转载 作者:行者123 更新时间:2023-11-30 02:10:22 26 4
gpt4 key购买 nike

我一直在尝试让 XInclude 在我的 XML 文档中工作,最后让它在 Oxygen XML 中工作,我用 Oxygen XML 来编写 XML 文档。

然后,我转到用 Java 编写的应用程序,但它似乎不支持任何形式的 XPointer 解析,除了使用以下内容:element(/1/2)。

显然,这是一个必须使用的糟糕方案,因为每次编辑文档时,XPointer 都需要更改以反射(reflect) XML 中节点的新位置!

我工作的方案只是在目标文档中使用 xml:id:

<foo>
<bar xml:id="ABCD" />
</foo>

然后,在另一个文档中:

<lorem>
<ipsum>
<xi:include href="target.xml" xpointer="ABCD" />
</ipsum>
</lorem>

我预计(并且正在吸入氧气)会产生如下结果:

<lorem>
<ipsum>
<bar xml:id="ABCD" />
</ipsum>
</lorem>.

但是,在 Java 中它会失败:

Resource error reading file as XML (href='data/target.xml'). Reason: XPointer resolution unsuccessful.

但是,如果我更改包含标记以使用

xpointer="element(/1/1)"

那么它工作得非常好 - 但是,正如我所说,这是一个非常糟糕的解决方案。

我只是使用 Java 运行时 (1.8) 中包含的实现。

这是我正在使用的代码:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setXIncludeAware(true);
Source resultSource = new
StreamSource(Gdx.files.internal("data/result.xsd").read());
Source targetSource = new
StreamSource(Gdx.files.internal("data/target.xsd").read());
Source[] schemaFiles = {targetSource, resultSource};
schema =
SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema")
.newSchema(schemaFiles);
factory.setSchema(schema);
builder = factory.newDocumentBuilder();
itemDoc = builder.parse(new
InputSource(Gdx.files.internal("data/result.xml").read()));

最佳答案

根据Apache Xerces's docs on XInclude (Java内部用于XML解析)

for shorthand pointers and element() XPointers, currently only DTD-determined IDs are supported.

这意味着您需要将如下所示的标记声明放入 target.xml 文件中(告诉 XML 解析器 id 属性将被视为具有 ID 语义的属性,并告诉 XInclude 将“裸”XPointers 解释为 ID 引用):

<!DOCTYPE foo [
<!ATTLIST bar id ID #IMPLIED>
]>
<foo>
<bar id="ABCD"/>
</foo>

如果您现在使用以下文档作为源 XML(您在示例代码中将其命名为 result.xml,并且我已将其编辑为包含 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 文件):

<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 模式的潜在交互,例如。在 XInclude Schema/Namespace Validation? 中讨论,以及 Duplicate some parts of XML without rewriting them 中讨论的潜在替代方案。

关于java - 尝试将 XInclude 与 Java 结合使用并使用 xml :id 解析片段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50294372/

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