[英]Remove XML node based on attribute value
我有以下 XML 文件,如果 EventType 匹配啟動或分配,我試圖從中刪除整個 AuditTrailEntry 節點。 我在 stackoverflow 上看到過類似的情況,但解決方案對我不起作用,我總是收到錯誤 - NOT_FOUND_ERR: 如果 oldChild 不是該節點的子節點,則引發。 你知道如何解決這個問題嗎?
<AuditTrailEntry>
<Data>
<Attribute name="elementId">sid-9E1E4EAD-5182-482F-9D5C-10961CA5BE2D</Attribute>
<Attribute name="processId">sid-C83E31C0-4CCC-4763-90C2-E09F1537D1EC</Attribute>
</Data>
<WorkflowModelElement>Test</WorkflowModelElement>
<EventType>assign</EventType>
<Timestamp>2021-06-17T13:20:10.557+00:00</Timestamp>
</AuditTrailEntry>
<AuditTrailEntry>
<Data>
<Attribute name="elementId">sid-9E1E4EAD-5182-482F-9D5C-10961CA5BE2D</Attribute>
<Attribute name="processId">sid-C83E31C0-4CCC-4763-90C2-E09F1537D1EC</Attribute>
<Attribute name="resourceId">sid-B0EBDEE1-4649-4AB6-B9AD-159188A0A02E</Attribute>
</Data>
<WorkflowModelElement>Test</WorkflowModelElement>
<EventType>start</EventType>
<Timestamp>2021-06-17T13:56:47.003+00:00</Timestamp>
<Originator>Test-000002</Originator>
</AuditTrailEntry>
<AuditTrailEntry>
<Data>
<Attribute name="elementId">sid-9E1E4EAD-5182-482F-9D5C-10961CA5BE2D</Attribute>
<Attribute name="processId">sid-C83E31C0-4CCC-4763-90C2-E09F1537D1EC</Attribute>
<Attribute name="resourceCost">0.8558947222222222</Attribute>
<Attribute name="resourceId">sid-B0EBDEE1-4649-4AB6-B9AD-159188A0A02E</Attribute>
</Data>
<WorkflowModelElement>Test</WorkflowModelElement>
<EventType>complete</EventType>
<Timestamp>2021-06-17T14:01:27.114+00:00</Timestamp>
<Originator>Test-000002</Originator>
</AuditTrailEntry>
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.mxml");
Document XML_DOC = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(f);
NodeList entries = XML_DOC.getElementsByTagName("AuditTrailEntry");
//printDocument(XML_DOC);
for (int i = 0; i < entries.getLength(); i++) {
Node entry = entries.item(i);
if(elementStatus(entry)) {
XML_DOC.getChildNodes().item(0).removeChild(entry);
}}
// 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 elementStatus(Node node) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element e = (Element) node;
if (e.getElementsByTagName("EventType").item(0).getTextContent().contentEquals("start"))
return true;
}
return false;
}
}```
使用 XPath,事情變得容易多了:
XPath xpath = XPathFactory
.newInstance()
.newXPath();
String expression = "//AuditTrailEntry[EventType='assign' or EventType='start']";
NodeList list = (NodeList) xpath.evaluate(expression, XML_DOC, XPathConstants.NODESET);
for (int i=0; i < list.getLength(); ++i) {
Node target = list.item(i);
target.getParentNode().removeChild(target);
}
對於此類任務,最好使用XSLT 。
XML 文件應具有根節點的良好格式。
XSLT 具有所謂的身份轉換模式。
XSLT
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!--<xsl:template match="AuditTrailEntry[EventType=('assign','start')]"/>-->
<xsl:template match="AuditTrailEntry[EventType='assign' or EventType='start']"/>
</xsl:stylesheet>
Java
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*;
public class Process {
public static void main(String[] args) {
String XSLTFILE = "e:/Temp/Process.xslt";
String INFILE = "e:/Temp/Input.xml";
String OUTFILE = "e:/Temp/Output.xml";
try {
// I/O
StreamSource input = new StreamSource(new File(INFILE));
StreamSource xslt = new StreamSource(new File(XSLTFILE));
StreamResult output = new StreamResult(new File(OUTFILE));
// Transformation
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(xslt);
transformer.transform(input, output);
} catch (TransformerConfigurationException tce) {
tce.printStackTrace();
} catch (TransformerException te) {
te.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.