I need to do xml transformation with SAX parser, for that i need to remove namespace from the xml. Since we are handling with huge xml, i need to use SAX parser.
sample input xml:
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
xmlns:ns2="http://www.google.com/generation/type">
<ns2:meta>
<gender xmlns="" xmlns:ns5="http://www.google.com/generation">M</gender>
<dateOfBirth xmlns="" xmlns:ns5="http://www.google.com/generation">1976-07-19</dateOfBirth>
<ns2:languageRef>ENG</ns2:languageRef>
</ns2:meta>
<root>
with the help of SAX parser, i need the below output.
<root>
<meta>
<gender>M</gender>
<dateOfBirth>1976-07-19</dateOfBirth>
<languageRef>ENG</languageRef>
</ns2:meta>
<root>
Thanks in advance..
The code which i tried,
i tried with XMLFlterImpl,
XMLReader xr = new XMLFilterImpl(XMLReaderFactory.createXMLReader()) {
@Override
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
if (qName.contains(":")) {
String[] data = data = qName.split(":");
super.startElement(uri, localName, data[1], atts);
} else {
super.startElement(uri, localName, qName, atts);
}
}
this removes the element name prefix(namespace), but not sure how to remove the namespace attributes
EDIT:
Ok, with direction from comments from @MichaelKay, here is my updated answer.
To remove namespace from tags:
As suggested in his answer, the startElement
should have ""
in place of uri
. What about Ending tag ?:
In your question I don't understand why you want ns2
for ending meta
tag particularly when you want to remove it for the starting tag.
I assume you want it to be removed for ending tag too. So similarly endElement
should also have ""
in place of uri
.
Filter XMLNS attributes:
You could create a new AttributesImpl
. Then go through the list of attributes and check if the QName
starts with xmlns
, if not add it to the AttributesImpl
and use it in the startElement
as :
super.startElement("", localName, data[1], aImpl);
Also note that as per @MartinHonnen, yes the attributes' uri
should also be "" and also the qName
should be without prefix as with elements. But if you want to keep the attributes' names as such ( which I don't think you want to ) you can just keep atts.getQName(i)
as is.
Also set Namespaces feature to false like :
xf.setFeature("http://xml.org/sax/features/namespaces", false);
Code :
try {
InputSource file = new InputSource("filterns.xml");
XMLFilterImpl xf = new XMLFilterImpl(
XMLReaderFactory.createXMLReader()) {
@Override
public void startElement(String uri, String localName,
String qName, Attributes atts) throws SAXException {
AttributesImpl aImpl = new AttributesImpl();
int l = atts.getLength();
for (int i = 0; i < l; i++) {
if (atts.getQName(i) != null
&& atts.getQName(i).startsWith("xmlns")) {
continue;
} else {
String aQName = atts.getQName(i);
String[] s = aQName.split(":");
if (s.length > 1) {
aQName = s[1];
}
aImpl.addAttribute("",
atts.getLocalName(i), aQName,
atts.getType(i), atts.getValue(i));
}
}
String[] s = qName.split(":");
if (s.length > 1) {
super.startElement("", localName, s[1], aImpl);
} else {
super.startElement("", localName, qName, aImpl);
}
}
@Override
public void endElement(String uri, String localName,
String qName) throws SAXException {
String[] s = qName.split(":");
if (s.length > 1) {
super.endElement("", localName, s[1]);
} else {
super.endElement("", localName, qName);
}
}
@Override
public void startPrefixMapping(String prefix, String uri) {
}
};
xf.setFeature("http://xml.org/sax/features/namespaces", false);
SAXSource src = new SAXSource(xf, file);
StringWriter stringWriter = new StringWriter();
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,"yes");
transformer.transform(src, new StreamResult(stringWriter));
String xml = stringWriter.toString();
System.out.println(xml);
} catch (Exception e) {
e.printStackTrace();
}