English 中文(简体)
使用 Java 从匹配属性名的 XML 文件中删除所有 xml 属性?
原标题:Using Java to remove all xml attributes from a XML file that match a attribute-name?
  • 时间:2012-05-24 19:10:08
  •  标签:
  • java
  • 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

最佳回答

尝试 :

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

查询返回的节点似乎从文档中分离出来,所以Parent Node是无效的。 - 不,它们不是分离的,我更新了代码。

我发现了一个", http://www.ibm.com/developmenterworks/xml/library/x-xpathjava/index.html" rel=“nofollow” > 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

", id);
            dupes++;
        } else {
            ids.add(id);
        }
    }

    System.out.format("Total ids = %d
 Total Duplicates = %d
", 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);
}
问题回答

以下是解决问题的最终代码:

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

", id);
                dupes++;
            } else {
                ids.add(id);
            }
        }

        System.out.format("Total ids = %d
 Total Duplicates = %d
", 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

NamedNodeMap attributes = node.getAttributes();
attributes.removeNamedItem(attName);




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签