mirror of https://github.com/apache/nifi.git
NIFI-1421 Update SplitXML to support namespace declarations
This commit is contained in:
parent
92062f9beb
commit
68a9375f3e
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue