Что делать если вам надо отредактировать (в частности вырезать ненужные теги со всей дальнейшей иерархией) довольно большой xml-файл, а под рукой только слабый компьютер с текстовым редактором типа «блокнот» и установленной java-машиной?
Поиск в гугле готовых вариантов не выявило полностью подходящего решения, поэтому, из того, что нашлось был склепан код описанный ниже в заметке.
importjavax.xml.parsers.*;importjavax.xml.transform.TransformerConfigurationException;importjavax.xml.transform.TransformerException;importorg.w3c.dom.*;importjava.io.*;importjava.io.File;importjavax.xml.parsers.DocumentBuilder;importjavax.xml.parsers.DocumentBuilderFactory;importjavax.xml.transform.Result;importjavax.xml.transform.Source;importjavax.xml.transform.Transformer;importjavax.xml.transform.TransformerFactory;importjavax.xml.transform.dom.DOMSource;importjavax.xml.transform.stream.StreamResult;importorg.w3c.dom.Document;importorg.xml.sax.SAXException;publicclass parsetest {publicstaticvoid main(String[] args)throws ParserConfigurationException, SAXException, IOException{System.out.println("start xml parsing");
parsetest test =new parsetest();String fileName ="test_file.xml";String tagFilter ="filter_tag";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder =null;File file =newFile("c:\\javaprojects\\xml_parser\\test_file.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();Document document = db.parse(file);
document.getDocumentElement().normalize();try{
builder = factory.newDocumentBuilder();
document = builder.parse(newFile(fileName));
test.filterElements(document, tagFilter);
test.printNodeElements(document);}catch(Exception e){
e.printStackTrace();}}// filter all elements whose tag name = filter_tagpublicvoid filterElements(Node parent, String filter)throws TransformerConfigurationException, TransformerException {
NodeList children = parent.getChildNodes();for(int i =0; i < children.getLength(); i++){
Node child = children.item(i);// only interested in elementsif(child.getNodeType()== Node.ELEMENT_NODE){// remove elements whose tag name = filter// otherwise check its children for filtering with a recursive callif(child.getNodeName().equals(filter)){
parent.removeChild(child);}else{
filterElements(child, filter);}}}
Source source =new DOMSource(parent);File new_file =newFile("c:\\javaprojects\\xml_parser\\new_test_file.xml");
Result result =new StreamResult(new_file);// Write the DOM document to the file
Transformer xformer = TransformerFactory.newInstance().newTransformer();
xformer.transform(source, result);}// print a nodes elements and childrenpublicvoid printNodeElements(Node node){System.out.println(node.getNodeName());
NodeList children = node.getChildNodes();for(int i =0; i < children.getLength(); i++){
Node child = children.item(i);if(child.getNodeType()== Node.ELEMENT_NODE){
printNodeElements(child);}}}}
Комментариев в коде не так много, да они и на английском так что немного описания принципов работы ниже.
Класс использует жестко прописанные в коде имя входного файла, название фильтруемого тега, имя выходного файла.
В содержимом входного файла отфильтровывается/вырезается все содержимое и все вхождения тега указанного как tagFilter, включая все вложенное содержание и сами теги. Фильтрацией занимается метод filterElements, метод printNodeElements — вспомогательный, распечатывает в output IDE (если запускать в ней) все xml-теги документа.
Например
Было:
<document><first>
text
</first><second><third>
moar text
</third></second></document>
Стало (с tagFilter = 'second'):
<document><first>
text
</first></document>
Скорее всего представленный код очередной «ашанбайк», но если есть конструктивная критика — вэлком в комментарии.