【问题标题】:Trying to use XInclude with Java and resolving the fragment with xml:id尝试将 XInclude 与 Java 一起使用并使用 xml:id 解析片段
【发布时间】:2018-05-11 14:16:50
【问题描述】:

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

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

显然,这是一个糟糕的方案,因为每次编辑文档时,XPointer 都需要更改以反映节点在 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 中它失败了:

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

但是,如果我将包含标签更改为使用

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()));

【问题讨论】:

    标签: java xml jaxp xinclude xpointer


    【解决方案1】:

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

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

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

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

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

    <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 文件中):

    <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 Schema 验证,我还想指出 XInclude 与 XML Schema 的潜在交互,例如。在XInclude Schema/Namespace Validation? 中讨论,也是Duplicate some parts of XML without rewriting them 中讨论的潜在替代方案。

    【讨论】:

    • 谢谢 - 这似乎让它工作了,虽然我不得不使用 DTD 是一个很大的耻辱(恕我直言)。但是,我可以忍受它,因为它只是一个定义一个属性的微小属性。考虑到这些技术有多老,我真的很惊讶解析器不支持 XML Schema 定义的 ID——这将是理想的。有两种 XML 变体可供我使用您发布的替代方案,而且我已经很好地使用了 XInclude 和 XML Schema。
    猜你喜欢
    • 2013-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-10
    • 1970-01-01
    • 1970-01-01
    • 2012-02-26
    相关资源
    最近更新 更多