我有以下XML,如果状态匹配为DEACTIVATED,我将尝试从其中删除整个节点。
下面是 input.xml
<devicesInfo>
<deviceID>DEVICE1</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>ACTIVE</status>
</devicesInfo>
<devicesInfo>
<deviceID>DEVICE2</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>DEACTIVATED</status>
</devicesInfo>
<devicesInfo>
<deviceID>DEVICE3</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>ACTIVE</status>
</devicesInfo>
<devicesInfo>
<deviceID>DEVICE4</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>ACTIVE</status>
</devicesInfo>
,所需的输出为:
<devicesInfo>
<deviceID>DEVICE1</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>ACTIVE</status>
</devicesInfo>
<devicesInfo>
<deviceID>DEVICE3</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>ACTIVE</status>
</devicesInfo>
<devicesInfo>
<deviceID>DEVICE4</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>ACTIVE</status>
</devicesInfo>
我已经能够提取与状态已停用相匹配的deviceID,但是在删除整个节点方面却很困难
void removeDeactivatedDevices() throws SAXException, IOException, ParserConfigurationException {
String device;
try {
File inputFile = new File(input.xml);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(inputFile);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("devicesInfo");
for (int i = 0; i < nList.getLength(); i++) {
Node nNode = nList.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
if (eElement.getElementsByTagName("status").item(0).getTextContent().contentEquals("DEACTIVATED")) {
device = eElement.getElementsByTagName("deviceID").item(0).getTextContent();
// print out the devices that match this status
System.out.println(device);
// HELP Need to delete parent node of that device...
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
因此,当我运行它时,我得到:
DEVICE1
DEVICE3
DEVICE4
我想要的是返回的完整XML,而不包含DEACTIVATED Status项目。
答案 0 :(得分:1)
好吧,假设您正在使用org.w3c.dom.*
库来解析XML文档,这应该很容易。只需使用Document.removeChild(node)
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class MainClass {
public static void main(String[] args) throws Exception {
File f = new File("input.xml");
Document XML_DOC = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(f);
NodeList devices = XML_DOC.getElementsByTagName("devicesInfo");
printDocument(XML_DOC);
for (int i = 0; i < devices.getLength(); i++) {
Node device = devices.item(i);
if(isDeviceDeactivated(device))
//remove from .item(0) because we have to remove them from the <devices> node
XML_DOC.getChildNodes().item(0).removeChild(device);
}
System.out.println("");System.out.println("");
System.out.println("------------------------------------");
printDocument(XML_DOC);
}
public static void printDocument(Document doc) throws IOException, TransformerException {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.transform(new DOMSource(doc), new StreamResult(new OutputStreamWriter(System.out, "UTF-8")));
}
public static boolean isDeviceDeactivated(Node node) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element e = (Element) node;
if (e.getElementsByTagName("status").item(0).getTextContent().contentEquals("DEACTIVATED"))
return true;
}
return false;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<devices>
<devicesInfo>
<deviceID>DEVICE1</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>ACTIVE</status>
</devicesInfo>
<devicesInfo>
<deviceID>DEVICE2</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>DEACTIVATED</status>
</devicesInfo>
<devicesInfo>
<deviceID>DEVICE3</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>ACTIVE</status>
</devicesInfo>
<devicesInfo>
<deviceID>DEVICE4</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>ACTIVE</status>
</devicesInfo>
</devices>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<devices>
<devicesInfo>
<deviceID>DEVICE1</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>ACTIVE</status>
</devicesInfo>
<devicesInfo>
<deviceID>DEVICE2</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>DEACTIVATED</status>
</devicesInfo>
<devicesInfo>
<deviceID>DEVICE3</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>ACTIVE</status>
</devicesInfo>
<devicesInfo>
<deviceID>DEVICE4</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>ACTIVE</status>
</devicesInfo>
</devices>
------------------------------------
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<devices>
<devicesInfo>
<deviceID>DEVICE1</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>ACTIVE</status>
</devicesInfo>
<devicesInfo>
<deviceID>DEVICE3</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>ACTIVE</status>
</devicesInfo>
<devicesInfo>
<deviceID>DEVICE4</deviceID>
<secondaryDevice>false</secondaryDevice>
<status>ACTIVE</status>
</devicesInfo>
</devices>
答案 1 :(得分:0)
我尝试了以下方法,也使用xPath解决了该问题
void removeDevicesWithDeactivatedStatus() throws SAXException, IOException, ParserConfigurationException, XPathExpressionException,
TransformerException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true); // never forget this!
Document document = dbf.newDocumentBuilder().parse(new File("input.xml"));
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
XPathExpression expression = xpath.compile("//devices/devicesinf[status/text()='DEACTIVATED']");
// 1) Get book titles written after 2001
Object result = expression.evaluate(document, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
int numberOfDeactivatedDevices = 0;
for (int i = 0; i < nodes.getLength(); i++) {
numberOfDeactivatedDevices = +i;
// System.out.println(nodes.item(i).getNodeValue() + " [" + i+"]");
Node b13Node = (Node) expression.evaluate(document, XPathConstants.NODE);
b13Node.getParentNode().removeChild(b13Node);
}
System.out.println("Deactivated devices removed: " + numberOfDeactivatedDevices);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.transform(new DOMSource(document), new StreamResult(new File("output.xml")));
//t.transform(new DOMSource(document), new StreamResult(System.out));
}