【问题标题】:Using Java to remove all xml attributes from a XML file that match a attribute-name?使用 Java 从与属性名称匹配的 XML 文件中删除所有 xml 属性?
【发布时间】:2012-05-31 09:51:50
【问题描述】:

我正在尝试使用 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

【问题讨论】:

    标签: java xml


    【解决方案1】:

    试试:

    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);
        }
    } 
    

    查询返回的节点似乎与文档分离,因此 getParentNode 为空。 - 不,它们没有分离,我更新了代码。

    我找到了一个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);
    
    } 
    

    更新:

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

    【讨论】:

    • 这个版本的 Document (org.w3c.dom.Document) 似乎没有我需要的 removeAttributeByName(String) 方法。
    • @djangofan 抱歉,我没有引起足够的重视。尝试获取元素,然后删除属性。
    • 我尝试了您的建议,但效果不佳。我更新了问题中的代码以反映更改。我会给你一个帮助我的投票。或者,也许它确实有效,我只是打印出错误的对象?需要研究...
    • @djangofan 第一个问题是我们使用 == 比较字符串 :) 修复了这个问题,现在我有一些例外。
    • 其实,我的错。我只是注意到我实际上并没有处理整个文档。我的代码正在处理过滤(通过 xpath)节点列表。所以,既然如此,我可能需要重新评估我正在做的事情。
    【解决方案2】:
    NamedNodeMap attributes = node.getAttributes();
    attributes.removeNamedItem(attName);
    

    【讨论】:

      【解决方案3】:

      这是解决问题的最终代码:

      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

      【讨论】:

        猜你喜欢
        • 2016-02-18
        • 2013-07-27
        • 1970-01-01
        • 2015-12-24
        • 2022-09-23
        • 1970-01-01
        • 2012-07-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多