Is it possible to ignore/skip nodes while parsing xml in Java
I'm trying to remove SOAP
and ns2
nodes from this XML :
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns2:createCustomer>
<Customer>
<CustomerId/>
<names>
<firstName>fName</firstName>
<lastName>lName</lastName>
<middleName>nName</middleName>
<nickName/>
开发者_StackOverflow </names>
<addressList>
<address>
<streetInfo>
<houseNumber>22</houseNumber>
<baseName>Street base name</baseName>
<district>kewl district</district>
</streetInfo>
<zipcode>22231</zipcode>
<state>xxx</state>
<country>xxxz</country>
<primary>true</primary>
</address>
</addressList>
<SSN>561381</SSN>
<phone>
<homePhone>123123123</homePhone>
<officePhone/>
<homePhone>21319414</homePhone>
</phone>
<preferred>true</preferred>
</Customer>
</ns2:createCustomer>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Is this possible before this :
Document doc = parser.parse(xmlFile);
NodeList startlist = doc.getChildNodes();
I tried to read this as String then writing it back to the XML file like this :
private void preParsing(String fileName,String ...tags) {
try {
BufferedReader br = new BufferedReader(new FileReader(new File(fileName)));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
for (String string : tags) {
if(!line.contains(string)){
sb.append(line);
sb.append("\n");
}
}
}
System.out.println(sb.toString());
br.close();
} catch (IOException e) {
System.err.println("Error occured: " + e.getMessage());
}
}
It worked if I ignore only one tag like :
preParsing("src/main/resources/test.xml", "SOAP");
But it didn't work when I pass more than one tag argument to ignore/remove from file. I'm sure there is more elegant way of doing this I just can't think of any.
You could use a StAX filter:
class MyFilter implements EventFilter {
private final List<String> filtered = Arrays.asList("SOAP-ENV:Envelope",
"SOAP-ENV:Body", "ns2:createCustomer");
@Override
public boolean accept(XMLEvent event) {
if (event.isStartElement())
for (String elementName : filtered)
if (event.asStartElement().getName().getLocalPart().equals(
elementName))
return false;
if (event.isEndElement())
for (String elementName : filtered)
if (event.asEndElement().getName().getLocalPart().equals(
elementName))
return false;
return true;
}
}
Usage:
DOMResult result = new DOMResult();
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
xmlInputFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false);
XMLEventReader reader = xmlInputFactory
.createXMLEventReader(new StreamSource(new File("soap.xml")));
reader = xmlInputFactory.createFilteredReader(reader, new MyFilter());
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
transformer.transform(new StAXSource(reader), result);
Document document = (Document) result.getNode();
FYI: SOAP-ENV and ns2 are not elements; they are namespace prefixes. The document is malformed - there is missing namespace declarations & the above code is not what I would write for a valid namespaced document.
Your best bet is to load the document normally, and use XPath to get at the parts that you want.
There is some good info at How to read XML using XPath in Java
A common approach to manipulate XML documents, is to use XSLT. This e.g. allow you to write filters that can remove any tag in a specific namespace, and much more.
The XSLT language is quite different from Java, but there is a XSLT processor (check the Templates and Transformer classes) in Java since 1.4, so it is well supported.
精彩评论