Propagate prefixes to child element when printing XML DOM to String in Java
I am creating an XML with DOM api in java as shown below
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
Element root = document.createElement("root");
document.appendChild(root);
Element one = document.createElementNS("http://ns1", "one");
root.appendChild(one);
one.setPrefix("ns1");
Element two = document.createElementNS("http://ns1", "two");
one.appendChild(two);
whe开发者_运维技巧n printing the above DOM using the following piece of code the namespace declarations are generated on all the elements (in this case on both element one and two). how can i ensure that the prefixes for namespace declarations are inherited and that the transformer does not redeclare them on each element-
Code:
public static String transformDOMtoText(final org.w3c.dom.Node domElement) throws TransformerException {
final Transformer transformer = getTransformer();
final DOMSource domSource = new DOMSource(domElement);
final StringWriter stringWriter = new StringWriter();
final StreamResult result = new StreamResult(stringWriter);
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ //$NON-NLS-2$
transformer.setOutputProperty(
OutputKeys.OMIT_XML_DECLARATION, "yes"); //$NON-NLS-1$ //$NON-NLS-2$
transformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "1");
transformer.transform(domSource, result);
String text = stringWriter.toString();
return text.trim();
}
Current Output::
<root>
<ns1:one xmlns:ns1="http://ns1">
<two xmlns="http://ns1">
</two>
</ns1:one>
</root>
Expected Output::
<root>
<ns1:one xmlns:ns1="http://ns1">
<ns1:two>
</ns1:two>
</ns1:one>
</root>
The second attribute in createElementNS()
is a qualified name (QName). Therefore, if you don't specify a prefix for your element name, your element will be unprefixed and the namespace is added as a default namespace.
Instead of (=what you wrote)
Element two = document.createElementNS("http://ns1", "two");
specify explicitly the desired prefix for the element "two"
Element two = document.createElementNS("http://ns1", "ns1:two");
or extract the prefix from the parent element instead of hardcoding it
Element two = document.createElementNS("http://ns1", one.getPrefix() + ":" + "two");
Note that Node.getPrefix()
will return null
if the prefix is unspecified. Of course, storing the prefix in a String variable makes things easier.
PS. Those code samples are untested so correct result is not guaranteed, but this is how I think it should work.
精彩评论