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&b"> + <value>Hello & Goodbye</value> + </foo:subNode1> + <foo:subNode2 xmlns:goo="http://namespace/2"> + <goo:value>World</goo:value> + </foo:subNode2> + </node> +</bundle>
