Repository: nifi
Updated Branches:
  refs/heads/master d71266502 -> 4a5fb37b3


NIFI-1421 Update SplitXML to support namespace declarations


Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/68a9375f
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/68a9375f
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/68a9375f

Branch: refs/heads/master
Commit: 68a9375f3e22109c68d048748c66228de7a8b4c4
Parents: 92062f9
Author: Richard Miskin <[email protected]>
Authored: Thu Jan 21 20:35:44 2016 +0000
Committer: Richard Miskin <[email protected]>
Committed: Thu Jan 21 22:19:15 2016 +0000

----------------------------------------------------------------------
 .../nifi/processors/standard/SplitXml.java      | 34 ++++++++++++++++++++
 .../nifi/processors/standard/TestSplitXml.java  | 20 ++++++++++++
 .../src/test/resources/TestXml/namespace.xml    | 11 +++++++
 3 files changed, 65 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/68a9375f/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/SplitXml.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/SplitXml.java
 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/SplitXml.java
index a8453bb..6d5b30a 100644
--- 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/SplitXml.java
+++ 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/SplitXml.java
@@ -21,8 +21,10 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map.Entry;
 import java.util.Set;
 
 import javax.xml.parsers.ParserConfigurationException;
@@ -193,6 +195,7 @@ public class SplitXml extends AbstractProcessor {
         private final int splitDepth;
         private final StringBuilder sb = new StringBuilder(XML_PROLOGUE);
         private int depth = 0;
+        private HashMap<String, String> prefixMap = new HashMap<>();
 
         public XmlSplitterSaxParser(XmlElementNotifier notifier, int 
splitDepth) {
             this.notifier = notifier;
@@ -261,6 +264,7 @@ public class SplitXml extends AbstractProcessor {
 
         @Override
         public void endPrefixMapping(String prefix) throws SAXException {
+            prefixMap.remove(prefixToNamespace(prefix));
         }
 
         @Override
@@ -293,19 +297,49 @@ public class SplitXml extends AbstractProcessor {
                 sb.append("<");
                 sb.append(qName);
 
+                final Set<String> attributeNames = new HashSet<>();
                 int attCount = atts.getLength();
                 for (int i = 0; i < attCount; i++) {
                     String attName = atts.getQName(i);
+                    attributeNames.add(attName);
                     String attValue = 
StringEscapeUtils.escapeXml10(atts.getValue(i));
                     sb.append(" 
").append(attName).append("=").append("\"").append(attValue).append("\"");
                 }
 
+                // If this is the first node we're outputting write out
+                // any additional namespace declarations that are required
+                if (splitDepth == newDepth - 1) {
+                    for (Entry<String, String> entry : prefixMap.entrySet()) {
+                        // If we've already added this namespace as an 
attribute then continue
+                        if (attributeNames.contains(entry.getKey())) {
+                            continue;
+                        }
+                        sb.append(" ");
+                        sb.append(entry.getKey());
+                        sb.append("=\"");
+                        sb.append(entry.getValue());
+                        sb.append("\" ");
+                    }
+                }
+
                 sb.append(">");
             }
         }
 
         @Override
         public void startPrefixMapping(String prefix, String uri) throws 
SAXException {
+            final String ns = prefixToNamespace(prefix);
+            prefixMap.put(ns, uri);
+        }
+
+        private String prefixToNamespace(String prefix) {
+            final String ns;
+            if (prefix.length() == 0) {
+                ns = "xmlns";
+            } else {
+                ns="xmlns:"+prefix;
+            }
+            return ns;
         }
     }
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/68a9375f/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestSplitXml.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestSplitXml.java
 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestSplitXml.java
index a84e031..e0a2e09 100644
--- 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestSplitXml.java
+++ 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestSplitXml.java
@@ -92,6 +92,25 @@ public class TestSplitXml {
         parseFlowFiles(runner.getFlowFilesForRelationship(SplitXml.REL_SPLIT));
     }
 
+    @Test
+    public void testNamespaceDeclarations() throws Exception {
+        // Configure a namespace aware parser to ensure namespace
+        // declarations are handled correctly.
+        factory = SAXParserFactory.newInstance();
+        factory.setNamespaceAware(true);
+        saxParser = factory.newSAXParser( );
+
+        final TestRunner runner = TestRunners.newTestRunner(new SplitXml());
+        runner.setProperty(SplitXml.SPLIT_DEPTH, "3");
+        runner.enqueue(Paths.get("src/test/resources/TestXml/namespace.xml"));
+        runner.run();
+        runner.assertTransferCount(SplitXml.REL_ORIGINAL, 1);
+        runner.assertTransferCount(SplitXml.REL_SPLIT, 2);
+
+        
parseFlowFiles(runner.getFlowFilesForRelationship(SplitXml.REL_ORIGINAL));
+        parseFlowFiles(runner.getFlowFilesForRelationship(SplitXml.REL_SPLIT));
+    }
+
     public void parseFlowFiles(List<MockFlowFile> flowfiles) throws Exception, 
SAXException {
         for (MockFlowFile out : flowfiles) {
             final byte[] outData = out.toByteArray();
@@ -99,4 +118,5 @@ public class TestSplitXml {
             saxParser.parse(new InputSource(new StringReader(outXml)), new 
DefaultHandler());
         }
     }
+
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/68a9375f/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/resources/TestXml/namespace.xml
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/resources/TestXml/namespace.xml
 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/resources/TestXml/namespace.xml
new file mode 100755
index 0000000..821398b
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/resources/TestXml/namespace.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bundle xmlns:foo="http://namespace/1";>
+    <node>
+        <foo:subNode1 attribute="d&amp;b">
+            <value>Hello &amp; Goodbye</value>
+        </foo:subNode1>
+        <foo:subNode2 xmlns:goo="http://namespace/2";>
+            <goo:value>World</goo:value>
+        </foo:subNode2>
+    </node>
+</bundle>

Reply via email to