2012-05-24 3 views
7

Я пытаюсь использовать Java для удаления всех атрибутов xml из XML-файла, соответствующего имени-атрибуту. Я застрял в этой точке. В нижней части этого кода я могу получить значение атрибута каждого узла по мере прохождения цикла, но я не могу понять, как удалить атрибут из узла в целом. Есть идеи?Использование Java для удаления всех атрибутов xml из файла XML, соответствующего имени атрибута?

import java.io.IOException; 
import java.io.StringWriter; 

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.ParserConfigurationException; 
import javax.xml.transform.OutputKeys; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerConfigurationException; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.TransformerFactoryConfigurationError; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 

import org.w3c.dom.*; 
import org.xml.sax.SAXException; 


public class StripAttribute { 

    public static void main(String[] args) { 

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
    factory.setNamespaceAware(true); 
    org.w3c.dom.Document doc = null; 
    NodeList nodes = null; 
    try { 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder db = dbf.newDocumentBuilder(); 
     doc = db.parse("a.xml"); 
     nodes = doc.getChildNodes(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } catch (ParserConfigurationException e) { 
     e.printStackTrace(); 
    } catch (SAXException e) { 
     e.printStackTrace(); 
    } 
    for (int i = 0; i < nodes.getLength(); i++) { 
     String id = nodes.item(i).getNodeValue(); 
     if (id.equals("siteKey")) { 
     Element el = ((Attr) nodes.item(i)).getOwnerElement(); 
     el.removeAttribute(id); 
     } 
    } 

    Transformer transformer; 
    StreamResult result = null; 
    try { 
     transformer = TransformerFactory.newInstance().newTransformer(); 
     transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
     result = new StreamResult(new StringWriter()); 
     DOMSource source = new DOMSource(doc); 
     transformer.transform(source, result); 
    } catch (TransformerConfigurationException e) { 
     e.printStackTrace(); 
    } catch (TransformerFactoryConfigurationError e) { 
     e.printStackTrace(); 
    } catch (TransformerException e) { 
     e.printStackTrace(); 
    } 
    String xmlString = result.getWriter().toString(); 
    System.out.println(xmlString); 
    } 
}  

Вот образец XML я хочу, чтобы преобразовать:

https://gist.github.com/2784907

ответ

3

Try:

for (int i = 0; i < nodes.getLength(); i++) { 
    String id = nodes.item(i).getNodeValue(); 
    if (id.equals("siteKey")) { 
     //doc.removeChild(nodes.item(i)); 
     Element el = ((Attr) nodes.item(i)).getOwnerElement(); 
     el.removeAttribute(id); 
    } 
} 

Кажется, что узлы, возвращенные запросом отделены от document, поэтому getParentNode имеет значение null. - Нет, они не отстранены, я обновил код.

Я нашел article, в котором говорится, что узлы, возвращаемые XPathExpression, все еще прикреплены к документу.

Вы исходный код + выше изменение:

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

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
    factory.setNamespaceAware(true); 
    Document doc = null; 
    NodeList nodes = null; 
    Set<String> ids = null; 
    try { 
     doc = factory.newDocumentBuilder().parse(new File("d:/a.xml")); 

     XPathExpression expr = XPathFactory.newInstance().newXPath().compile("//@siteKey"); 
     ids = new HashSet<String>(); 
     nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); 
    } catch (SAXException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } catch (ParserConfigurationException e) { 
     e.printStackTrace(); 
    } catch (XPathExpressionException e) { 
     e.printStackTrace(); 
    } 

    for (int i = 0; i < nodes.getLength(); i++) { 
     String id = nodes.item(i).getNodeValue(); 
     if (id.equals("siteKey")) { 
      Element el = ((Attr) nodes.item(i)).getOwnerElement(); 
      el.removeAttribute(id); 
     } 
    } 

    int dupes = 0; 
    for (int i = 0; i < nodes.getLength(); i++) { 
     String id = nodes.item(i).getNodeValue(); 
     if (ids.contains(id)) { 
      System.out.format("%s is duplicate\n\n", id); 
      dupes++; 
     } else { 
      ids.add(id); 
     } 
    } 

    System.out.format("Total ids = %d\n Total Duplicates = %d\n", ids.size(), dupes); 

    Transformer transformer; 
    StreamResult result = null; 
    try { 
     transformer = TransformerFactory.newInstance().newTransformer(); 
     transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
     result = new StreamResult(new StringWriter()); 
     DOMSource source = new DOMSource(doc); 
     transformer.transform(source, result); 
    } catch (TransformerConfigurationException e) { 
     e.printStackTrace(); 
    } catch (TransformerFactoryConfigurationError e) { 
     e.printStackTrace(); 
    } catch (TransformerException e) { 
     e.printStackTrace(); 
    } 

    String xmlString = result.getWriter().toString(); 
    System.out.println(xmlString); 

} 

Update:

for (int i = 0; i < nodes.getLength(); i++) { 
    String id = nodes.item(i).getNodeValue(); 
    Element el = ((Attr) nodes.item(i)).getOwnerElement(); 
    el.removeAttribute(id); 
} 
+0

Эта версия документа (org.w3c.dom.Document) не кажется, есть метод removeAttributeByName (String), которая является то, что мне нужно. – djangofan

+0

@djangofan извините, я не уделял достаточного внимания. Попробуйте получить элемент, а затем удалить атрибуты. – tibtof

+0

Я попробовал ваше предложение, но это не совсем сработало. Я обновил свой код в своем вопросе, чтобы отразить изменения. Я дам вам помощь, чтобы помочь мне. Или, может быть, это сработало, и я просто распечатываю неправильный объект? Нужно исследовать ... – djangofan

0

Вот окончательный код, который был решен вопрос:

import java.io.File; 
import java.io.IOException; 
import java.io.StringWriter; 
import java.util.HashSet; 
import java.util.Set; 

import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.ParserConfigurationException; 
import javax.xml.transform.OutputKeys; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerConfigurationException; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.TransformerFactoryConfigurationError; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 
import javax.xml.xpath.XPathConstants; 
import javax.xml.xpath.XPathExpression; 
import javax.xml.xpath.XPathExpressionException; 
import javax.xml.xpath.XPathFactory; 

import org.w3c.dom.*; 
import org.xml.sax.SAXException; 


public class StripAttributes { 

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

     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
     factory.setNamespaceAware(true); 
     Document doc = null; 
     NodeList nodes = null; 
     Set<String> ids = null; 
     try { 
      doc = factory.newDocumentBuilder().parse(new File("a.xml")); 

      XPathExpression expr = XPathFactory.newInstance().newXPath() 
        .compile("//@siteKey"); 
      ids = new HashSet<String>(); 
      nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); 
     } catch (SAXException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (ParserConfigurationException e) { 
      e.printStackTrace(); 
     } catch (XPathExpressionException e) { 
      e.printStackTrace(); 
     } 

     for (int i = 0; i < nodes.getLength(); i++) { 
      System.out.println("."); //progress indicator 
      Element el = ((Attr) nodes.item(i)).getOwnerElement(); 
      if (el.hasAttribute("siteKey")) el.removeAttribute("siteKey"); 
     } 

     int dupes = 0; 
     for (int i = 0; i < nodes.getLength(); i++) { 
      String id = nodes.item(i).getNodeValue(); 
      if (ids.contains(id)) { 
       System.out.format("%s is duplicate\n\n", id); 
       dupes++; 
      } else { 
       ids.add(id); 
      } 
     } 

     System.out.format("Total ids = %d\n Total Duplicates = %d\n", ids 
       .size(), dupes); 

     Transformer transformer; 
     StreamResult result = null; 
     try { 
      transformer = TransformerFactory.newInstance().newTransformer(); 
      transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
      result = new StreamResult(new StringWriter()); 
      DOMSource source = new DOMSource(doc); 
      transformer.transform(source, result); 
     } catch (TransformerConfigurationException e) { 
      e.printStackTrace(); 
     } catch (TransformerFactoryConfigurationError e) { 
      e.printStackTrace(); 
     } catch (TransformerException e) { 
      e.printStackTrace(); 
     } 

     String xmlString = result.getWriter().toString(); 
     System.out.println(xmlString); 

    } 
}  

Кроме того, здесь является ссылкой на перевод Groovy этого кода:

https://gist.github.com/2789163

1
NamedNodeMap attributes = node.getAttributes(); 
attributes.removeNamedItem(attName); 
Смежные вопросы