尝试在Java中使用XInclude并使用xml:id解析该片段 [英] Trying to use XInclude with Java and resolving the fragment with xml:id

查看:104
本文介绍了尝试在Java中使用XInclude并使用xml:id解析该片段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图让XInclude在我的XML文档中工作,最后使它在Oxygen XML中工作,而我正使用Oxygen XML编写XML文档.

I've been trying to get XInclude working in my XML document and finally have it working in Oxygen XML, which I'm using to author the XML documents.

然后我进入了用Java编写的应用程序,但是它似乎不支持任何形式的XPointer解析,除非使用诸如element(/1/2)之类的东西.

I then went to my app, written in Java, but it doesn't seem to support any form of XPointer resolution except using something like: element(/1/2).

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

This is, obviously, an awful scheme to have to use since every time the document is edited the XPointer needs changing to reflect the new position of the node in the XML!

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

The scheme I had working simply used xml:id in the target document:

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

,然后在另一个文档中:

and then, in the other document:

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

我期望(并且正在吸收氧气)会导致以下结果:

Which I anticipate (and am getting in Oxygen) results in something like:

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

但是,在Java中,它失败并显示:

However, in Java it fails with:

读取XML格式的文件时发生资源错误(href ='data/target.xml').原因: XPointer解析失败.

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

但是,如果我将include标记更改为使用

If, however, I change the include tag to use

xpointer="element(/1/1)"

然后它很好地工作-但是,正如我所说的,这是一个非常糟糕的解决方案.

then it works very nicely - but, as I've said, that's a very poor solution.

我只是在使用Java运行时(1.8)随附的实现.

I'm simply using the implementations that are included with the Java runtime (1.8).

这是我正在使用的代码:

Here's the code I'm using:

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在XInclude上的文档(内部用于Java进行XML解析)

According to Apache Xerces's docs on XInclude (which is used internally for XML parsing by Java)

对于速记指针和element()XPointers,目前仅支持DTD确定的ID.

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

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

This means that you need to put markup declarations such as the following into your target.xml file (telling the XML parser that the id attribute is to be treated as attribute with ID semantics, and telling XInclude to interpret "bare" XPointers as ID references):

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

如果您现在使用以下文档作为源XML(在示例代码中将其命名为result.xml,并且我对其进行了编辑以包含用于xi的XInclude名称空间URI绑定)

If you now use the following document as your source XML (which you've named result.xml in your example code, and which I've edited to contain an XInclude namespace URI binding for xi)

<lorem xmlns:xi="http://www.w3.org/2001/XInclude">
  <ipsum>
    <xi:include href="target.xml" xpointer="ABCD"/>
  </ipsum>
</lorem>

然后,Xerces将建立一个Document,其中已根据需要执行了XInclude处理(其中,我已将示例数据放入与result.xml文件位于同一目录中的target.xml文件中):

then Xerces will build up a Document where XInclude processing has been performed as desired (where i've put your example data into the target.xml file in the same directory as the result.xml file):

<lorem xmlns:xi="http://www.w3.org/2001/XInclude">
  <ipsum>
    <bar id="ABCD" xml:base="target.xml"/>
  </ipsum>
</lorem>

从您的示例中简化了我用来生成文档的Java代码,并且其中不包含第三方库:

The Java code I've used to produce the document is simplified from your example and doesn't contain third-party libs:

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 Schema验证时,我还想指出XInclude与XML Schema的潜在交互作用,例如.在 XInclude Schema/Namespace Validation?中进行了讨论,在

Seeing as you also use XML Schema validation, I'd also like to point out the potential interaction of XInclude with XML Schema as eg. discussed in XInclude Schema/Namespace Validation?, and also a potential alternative discussed in Duplicate some parts of XML without rewriting them .

这篇关于尝试在Java中使用XInclude并使用xml:id解析该片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆