diff --git a/src/main/java/io/fixprotocol/xml/XmlMerge.java b/src/main/java/io/fixprotocol/xml/XmlMerge.java
index 788cc11..7d95269 100644
--- a/src/main/java/io/fixprotocol/xml/XmlMerge.java
+++ b/src/main/java/io/fixprotocol/xml/XmlMerge.java
@@ -35,16 +35,14 @@
import javax.xml.xpath.XPathFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.Text;
+import org.w3c.dom.*;
import org.xml.sax.SAXException;
import io.fixprotocol.orchestra.event.EventListener;
import io.fixprotocol.orchestra.event.EventListenerFactory;
import io.fixprotocol.orchestra.event.TeeEventListener;
+import static org.w3c.dom.Node.ATTRIBUTE_NODE;
+
/**
* Merges a difference file created by {@link XmlDiff} into a baseline XML file to create a new XML
* file
@@ -262,16 +260,25 @@ private void remove(final Document doc, XPath xpathEvaluator, Element patchOpEle
final Node node =
(Node) xpathEvaluator.compile(xpathExpression).evaluate(doc, XPathConstants.NODE);
if (node != null) {
- final Node parent = node.getParentNode();
- if (parent != null) {
- final NodeList children = parent.getChildNodes();
- for (int i = 0; i < children.getLength(); i++) {
- if (children.item(i) == node) {
- parent.removeChild(node);
- break;
+ if (ATTRIBUTE_NODE == node.getNodeType()) {
+ Attr attr = (Attr) node;
+ Element parent = attr.getOwnerElement();
+ parent.removeAttributeNode(attr);
+ } else {
+ Node parent = node.getParentNode();
+ if (parent != null) {
+ final NodeList children = parent.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node item = children.item(i);
+ if (item == node) {
+ parent.removeChild(node);
+ break;
+ }
}
}
}
+ } else {
+ eventLogger.warn("XPath expression to remove not found; {0}", xpathExpression);
}
} catch (final XPathExpressionException e) {
errors++;
@@ -304,7 +311,7 @@ private void replace(final Document doc, XPath xpathEvaluator, Element patchOpEl
text.setNodeValue(value);
siteNode.appendChild(text);
break;
- case Node.ATTRIBUTE_NODE:
+ case ATTRIBUTE_NODE:
case Node.TEXT_NODE:
siteNode.setNodeValue(value);
break;
diff --git a/src/test/java/io/fixprotocol/xml/XmlDiffTest.java b/src/test/java/io/fixprotocol/xml/XmlDiffTest.java
index 476a92b..7f2d232 100644
--- a/src/test/java/io/fixprotocol/xml/XmlDiffTest.java
+++ b/src/test/java/io/fixprotocol/xml/XmlDiffTest.java
@@ -34,6 +34,8 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
class CustomLogFactory implements LoggerContextFactory {
private final org.apache.logging.log4j.spi.LoggerContext ctx;
@@ -72,12 +74,15 @@ public void removeContext(org.apache.logging.log4j.spi.LoggerContext context) {
public class XmlDiffTest {
+ private static DocumentBuilder docBuilder;
private XmlMerge xmlMerge;
@BeforeAll
public static void setupOnce() throws Exception {
new File("target/test").mkdirs();
LogManager.setFactory(new CustomLogFactory());
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+ docBuilder = docFactory.newDocumentBuilder();
}
/**
@@ -95,9 +100,6 @@ public void unordered() throws Exception {
final String diffFilename = "target/test/unordereddiff.xml";
XmlDiff.main(new String[] {"src/test/resources/DiffTest1.xml", "src/test/resources/DiffTest2.xml", diffFilename, "-u"});
-
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(diffFilename);
// Expectation:
@@ -127,9 +129,6 @@ public void ordered() throws Exception {
final String diffFilename = "target/test/ordereddiff.xml";
XmlDiff.main(new String[] {"src/test/resources/DiffTest1.xml", "src/test/resources/DiffTest2.xml", diffFilename});
-
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(diffFilename);
assertEquals(3, doc.getElementsByTagName("add").getLength());
@@ -160,11 +159,29 @@ public void epDiff() throws Exception {
}
}
-
@Test
public void xsdDiff() throws Exception {
final String diffFilename = "target/test/xsddiff.xml";
XmlDiff.main(new String[] {"src/test/resources/Enums-new.xsd", "src/test/resources/Enums-old.xsd", diffFilename, "-u"});
}
+ @Test
+ public void removeAttribute() throws Exception {
+ final String mergedFilename = "target/test/Instrument-merged.xml";
+ final String diffFilename = "src/test/resources/Instrument-diff.xml";
+ final String baseFilename = "src/test/resources/Instrument-base.xml";
+
+ try (
+ final FileInputStream is1Baseline = new FileInputStream(baseFilename);
+ final FileInputStream isDiff = new FileInputStream(diffFilename);
+ final FileOutputStream osMerge = new FileOutputStream(mergedFilename)) {
+ xmlMerge.merge(is1Baseline, isDiff, osMerge);
+
+ Document doc = docBuilder.parse(mergedFilename);
+ NodeList elements = doc.getElementsByTagName("fixr:component");
+ Element element = (Element) elements.item(0);
+ assertEquals(0, element.getAttribute("added").length());
+ }
+ }
+
}
diff --git a/src/test/resources/Instrument-base.xml b/src/test/resources/Instrument-base.xml
new file mode 100644
index 0000000..aa59d97
--- /dev/null
+++ b/src/test/resources/Instrument-base.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/src/test/resources/Instrument-diff.xml b/src/test/resources/Instrument-diff.xml
new file mode 100644
index 0000000..bd0fe98
--- /dev/null
+++ b/src/test/resources/Instrument-diff.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file