Search code examples
javaxmldtdxinclude

The prefix "xi" for element "xi:include" is not bound while using DTD


I'd like to use xincludes to reduce the size of a xml file that has grown to 21K+ LOC in a java 8 app but am running into the following error:

Nov 04, 2019 4:27:44 PM com.s3.config.XMLValidatorErrorHandler fatalError
SEVERE: Could not parse file (/path/to/CS_Config.xml). line: 80, The prefix "xi" for element "xi:include" is not bound.

We currently are using a DTD for our XML validation an though I have read that schema is a better long term solution I'd like to just get something working in the meanwhile since I'm not sure how long it will take to convert to a schema document.

Here is our line 80 of our main config where I'm adding the include:

<xi:include href="ParametersModbus.xml" />
<xi:include href="Parameters.xml" />
<xi:include href="ParametersVirtual.xml" />

So far I've added this to our DTD:

<!ELEMENT xi:include (#PCDATA)>
<!ATTLIST xi:include 
    href CDATA #IMPLIED
>

and

<!ELEMENT Device (xi:include*,Peripheral*,VirtualPeripheral*,Camera*,MachineSync?,MachineChangeDetection?,Buffers?,Expressions?)>

I do have these two mods from reading others post on xinclude:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setXIncludeAware(true);
dbf.setNamespaceAware(true);

Not sure if I need to add the xpointer references but someone can advise.

Here are some related post: XML Namespaces and DTD validation Trying to use XInclude with Java and resolving the fragment with xml:id Default support for xinclude in Java 6?

11/5 UPDATE imhotap's answer below resolved my immediate issue and when validation is turned off we are able to process the includes. However when I turn on validation I get this behavior:

Nov 05, 2019 3:23:42 PM com.s3.config.XMLValidatorErrorHandler error
SEVERE: Could not parse XML file (/home/jchan/eclipse-workspace/filtec-src/src/gui/test_configs/FIL0000/CS_Config.xml). line: 1, Document is invalid: no grammar found.
Nov 05, 2019 3:23:42 PM com.s3.config.XMLValidatorErrorHandler error
SEVERE: Could not parse XML file (/home/jchan/eclipse-workspace/filtec-src/src/gui/test_configs/FIL0000/CS_Config.xml). line: 1, Document root element "Peripheral", must match DOCTYPE root "null". 

Is there something I need to do to not need to define a root element in the DTD?

11/5 UPDATE 2 Looks like each of my include snippets just needed to have the DOCTYPE tags preceding the root elements of the files being included. So in my case it was:

<?xml version="1.0"?>
<!DOCTYPE VirtualPeripheral SYSTEM "../../../architecture/peripheral-description/CS_Config.dtd">

Solution

  • Even when you're declaring "xi:include" as an element, you must still bind the "xi" namespace to the XInclude namespace URI. Try declaring "xmlns:xi" as a #FIXED attribute on your "xi:include" element like this:

    <!ELEMENT xi:include EMPTY>
    <!ATTLIST xi:include 
      href CDATA #IMPLIED
      xmlns:xi CDATA #FIXED "http://www.w3.org/2001/XInclude">
    

    Not sure why you think XML Schema is a better long-term solution compared to plain SGML/XML DTDs for your application. If anything, XML Schema is much more complex and verbose, and has fewer implementations; yet some of its features, such as substitution groups, are actively warned against. Along the same line, the functionality you're using XInclude for in your example (inclusion of fragments from other files) can be much easier implemented using plain SGML/XML entity references ( see eg Include one XML within another XML and parse it with python).