Skip to main content

Unable to add entity reference node to DOM

5 replies [Last post]
minka99
Offline
Joined: 2008-03-27
Points: 0

Hi,
Are there any gotchas about adding entity reference Nodes to a DOM?
This program shows what for me was unexpected behavior.
The created EntityReference Node had only a name, no child that had the
replacement text. When I tried to add that Node to the DOM, nothing got added.

The test program also shows that the entity replacement is working fine with
the original source, '&h;' is replaced by 'hardcover' in the output.
But I am not able to add this entity reference to the node

Thanks!!

package javaTest;
import java.io.ByteArrayInputStream;
import java.io.OutputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.EntityReference;

import driver.beelucid.plugin.XmlException;

public class JavaTest1 {

public static void main(String[] args) throws Exception {

String xmlStr = "]>" + "" + "Pride And Prejudice" + "&h;" + "" + " ";

ByteArrayInputStream xml = new ByteArrayInputStream(xmlStr.getBytes());
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
Document n;
try {
DocumentBuilder builder = factory.newDocumentBuilder();
n = builder.parse(xml);
// Note if you look at the DocumentType returned by n.getDoctype() it has
// 'h' in it, but with no replacement text, no child.
EntityReference er = n.createEntityReference("h");

// From javadoc, the above 'createEntityReference' is supposed to do this:
//* Creates an EntityReference object. In addition, if the
//* referenced entity is known, the child list of the
//* EntityReference node is made the same as that of the
//* corresponding Entity node.
// but the child list is null.
// Isn't the entity 'h' known, see the xml above?

// The following doesn't do anything at all - WHY?
// It seems to me it ought to be adding the entity reference to the node.
n.getDocumentElement().getLastChild().appendChild(er);

// write out result: verify that the above line did nothing.
TransformerFactory xformFactory = TransformerFactory.newInstance();
Transformer idTransform = xformFactory.newTransformer();
Source input = new DOMSource(n);
OutputStream out = System.out;
Result output = new StreamResult(out);
idTransform.transform(input, output);
out.close();
}

catch (Exception e) {
throw new XmlException(e.getMessage());
}

}

}

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
joehw
Offline
Joined: 2004-12-15
Points: 0

At first glance, it looks like a bug to me because the javadocs for createEntityReference method was stated like this:
Creates an EntityReference object. In addition, if the referenced entity is known, the child list of the EntityReference node is made the same as that of the corresponding Entity node.

But the resulting entity ref in your case seemed to contain no child list. I thought the ref should be resolved after calling:
n.normalizeDocument();

Unfortunately, that didn't work for me. You may have to find another way to do this.

minka99
Offline
Joined: 2008-03-27
Points: 0

"the resulting entity ref in your case seemed to contain no child list. "

My first thought was that this was the bug. It should have a child list
because the entity is known - we know that it is known because it was
used in the replacement.

If I think it's a bug (and you don't) can I file it as a bug? ;-)

joehw
Offline
Joined: 2004-12-15
Points: 0

Here's what you would need to do in order to resolve the entity reference dynamically added:

Refer to http://java.sun.com/javase/6/docs/api/org/w3c/dom/DOMConfiguration.html

DOMConfiguration docConfig = n.getDomConfig();
docConfig.setParameter("entities", Boolean.FALSE);
... (after all is done but before transformation)
n.normalizeDocument();

Joe

minka99
Offline
Joined: 2008-03-27
Points: 0

Joe I tried your approach and I got no change in behavior. Is this a bug?
thanks,
minka99

package javaTest;
import java.io.ByteArrayInputStream;
import java.io.OutputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.Document;
import org.w3c.dom.Entity;
import org.w3c.dom.EntityReference;

public class JavaTest1 {

public static void main(String[] args) throws Exception {

String xmlStr = "]>" + "" + "Pride And Prejudice" + "&h;" + "" + " ";
ByteArrayInputStream xml = new ByteArrayInputStream(xmlStr.getBytes());

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setExpandEntityReferences(false); // true or false has no effect
Document n;
try {
DocumentBuilder builder = factory.newDocumentBuilder();
n = builder.parse(xml);
// Note if you look at the DocumentType returned by n.getDoctype() it has
// 'h' in it, but with no replacement text, no child.
DOMConfiguration docConfig = n.getDomConfig();
docConfig.setParameter("entities", Boolean.FALSE); Entity e = (Entity) n.getDoctype().getEntities().getNamedItem("h");
if (e.getFirstChild() == null) System.out.println("Entity h has no child");
EntityReference er = n.createEntityReference("h");

// From javadoc, the above 'createEntityReference' is supposed to do this:
//* Creates an EntityReference object. In addition, if the
//* referenced entity is known, the child list of the
//* EntityReference node is made the same as that of the
//* corresponding Entity node.
// but the child list is null.
// Isn't the entity 'h' known, see the xml above?
// The following doesn't do anything at all - WHY?
// It ought to be adding the entity reference h to the node, but does nothing.
n.getDocumentElement().getLastChild().appendChild(er);
n.normalizeDocument();
// write out result: verify that adding entity ref h did nothing.
TransformerFactory xformFactory = TransformerFactory.newInstance();
Transformer idTransform = xformFactory.newTransformer();
Source input = new DOMSource(n);
OutputStream out = System.out;
Result output = new StreamResult(out);
idTransform.transform(input, output);
out.close();
}

catch (Exception e) {

}

}

}

joehw
Offline
Joined: 2004-12-15
Points: 0

I checked and found that entities = doctype.getEntities() did not contain entity definitions, which made it impossible for the normalizeDocument() process to fix the entity reference. I'm not sure if this is a bug or if there's a property to enable it. I can do some further investigation. Unfortunately, that might have to wait until after JavaOne. Sorry.