how to add statement import into xml (schema/xsd) using java

37 Views Asked by At

i want to add import statement to an existing schema/xsd file using java, is there anyway we can add these to xsd?, I did try as below but getting error: "org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted."

Schema:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<!--    ommitted rest of the content-->
</xs:schema>

Want to add the import as below :

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="myownLocation"/>
    <!--    ommitted rest of the content-->
</xs:schema>

I used the below logic but failed with error:

org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted.

Document doc = DocumentBuilderFactory
                   .newInstance()
                   .newDocumentBuilder()
                   .parse(new FileInputStream("testXSD.xml"));
    
Element blobKey_E = doc.createElement("xs:import");
blobKey_E.setAttribute("namespace", "http://www.w3.org/2000/09/kk#");
blobKey_E.setAttribute("schemaLocation", "myownLocation");

doc.appendChild(blobKey_E);

        
TransformerFactory
        .newInstance()
        .newTransformer()
        .transform(new DOMSource(doc.getDocumentElement()), new 
StreamResult(System.out)); 
2

There are 2 best solutions below

0
Mads Hansen On BEST ANSWER

Your issue is that you are attempting to append the xs:import element to the root node (which is the parent of xs:schema) and would create two document elements. The concept of the root node may seem confusing and you might expect that to be xs:schema, but remember that you could have other top level nodes, such as comments or processing instructions - but you can only have one XML element as the child of the root node.

Instead, select the document element (which is the xs:schema element) with doc.getDocumentElement() and then append your xs:import element to it:

Element root = doc.getDocumentElement();
root.appendChild(blobKey_E);
0
Michael Kay On

I'm not sure why you have tagged the question "saxon" and then use DOM for the task, which is a very un-Saxon-like way of doing things.

My instinct would be a simple XSLT transformation:

 <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:template match="/xs:schema">
      <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xs:import namespace="http://www.w3.org/XML/1998/namespace"
                   schemaLocation="myownLocation"/>  
        <xsl:copy-of select="*"/>
      </xsl:copy>
    </xsl:template>
  </xsl:stylesheet>