You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@nifi.apache.org by sally <sa...@gmail.com> on 2017/10/14 17:16:35 UTC

nifi: How to update and trnaform xml file inside ExecuteScript processor

Question by sally sally 12 secs ago nifi-processorjavaapache-nifigroovy 
I want to read xml file from folder and i want to update it and make new
flowfile(my code will be placed in nifi processor) which will containt this
renewated data but i can't parse xml document properly i got error like
this:org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot
cast object 'com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl@181ae3f

1.what should i change?( except changing doc = builder.parse(inputStream)
with doc=builder.parse(file) because i need to use string data for later
processing)

Another reason why i can't fulfill my task is that i can't make flowfile in
which i would have placed all renewated xml data, for some reason i got
empty flowfile even if i use this doc=builder.parse(file) i means use config
file phisically( File file=new File('path')), what should i change to
improve this case.
if i use string content, should i use any alternative way to get xml tag
data except using NodeList( i mean is it possible to use any better use
case)? here is my groovy code:

import org.apache.commons.io.IOUtils;
 
import java.nio.charset.StandardCharsets;
 
import  java.io.RandomAccessFile;
 
import java.nio.channels.FileLock;
 
import java.io.BufferedReader;
 
import org.apache.commons.io.IOUtils;
 
import java.nio.charset.StandardCharsets;
 
File file =newFile("C://Users//user//Desktop//2//conf.xml");
 
String content ='';RandomAccessFile ini =newRandomAccessFile(file,"rws");
 
FileLock lock = ini.getChannel().lock();BufferedReader s;
 
DocumentBuilder dBuilder =null;Document doc=null;String
start,startDate,endDate,runAs,makeVersion,patch;
 
try{String sCurrentLine;
           
s=newBufferedReader(Channels.newReader(ini.getChannel(),"UTF-8"));while((sCurrentLine
= s.readLine())!=null){
                content+=sCurrentLine;}//make  xml
parsingDocumentBuilderFactory factory
=DocumentBuilderFactory.newInstance();DocumentBuilder builder =
factory.newDocumentBuilder();InputStream inputStream
=newByteArrayInputStream(content.getBytes());
            doc = builder.parse(inputStream);NodeList nList =
doc.getElementsByTagName("localAttributes");
 
for(int temp =0; temp < nList.getLength(); temp++){Node nNode =
nList.item(temp);
 
if(nNode.getNodeType()==Node.ELEMENT_NODE){Element eElement =(Element)
nNode;
                    start =
eElement.getElementsByTagName("start").item(0).getTextContent();
                    startDate =
eElement.getElementsByTagName("startDate").item(0).getTextContent();
                    endDate =
eElement.getElementsByTagName("endDate").item(0).getTextContent();
                    patch =
eElement.getElementsByTagName("patch").item(0).getTextContent();
                    runAs =
eElement.getElementsByTagName("runAs").item(0).getTextContent();
                    makeVersion =
eElement.getElementsByTagName("makeVersion").item(0).getTextContent();}}
            flowFile1 = session.putAttribute(flowFile1,"start", start);
            flowFile1 = session.putAttribute(flowFile1,"startDate",
startDate);
            flowFile1 = session.putAttribute(flowFile1,"endDate", endDate);
            flowFile1 = session.putAttribute(flowFile1,"runAs", runAs);
            flowFile1 = session.putAttribute(flowFile1,"patch", patch);
            flowFile1 = session.putAttribute(flowFile1,"makeVersion",
makeVersion);
 
            flowFile1 =
session.putAttribute(flowFile1,"filename","conf.xml");
 
DocumentBuilderFactory builderFactory =DocumentBuilderFactory.newInstance();
 
DocumentBuilder builder = builderFactory.newDocumentBuilder();Document
xmlDocument = builder.parse(inputStream);
 
XPath xPath =XPathFactory.newInstance().newXPath();XPathExpression
myNodeList =(XPathExpression) xPath.compile("/localAttributes");
 
Node nodeGettingChanged =(Node)
myNodeList.evaluate(xmlDocument,XPathConstants.NODE);NodeList childNodes =
nodeGettingChanged.getChildNodes();for(int i =0; i !=
childNodes.getLength();++i){Node child = childNodes.item(i);
 
if(!(child
instanceofElement))continue;if(child.getNodeName().equals("runAs"))
                    child.getFirstChild().setNodeValue("false");}
 
TransformerFactory transformerFactory
=TransformerFactory.newInstance();Transformer transformer =null;
            transformer = transformerFactory.newTransformer();DOMSource
source =newDOMSource(xmlDocument);StreamResult file1
=newStreamResult(inputStream);
 
try{
                transformer.transform(source,
file1);}catch(TransformerException e){
                e.printStackTrace();}
            session.write(flowFile1,newStreamCallback(){@Overridepublicvoid
process(InputStream inputStream,OutputStream outputStream)throwsIOException{
 
TransformerFactory transformerFactory =TransformerFactory.newInstance();
 
Transformer transformer =null;try{
                        transformer =
transformerFactory.newTransformer();}catch(TransformerConfigurationException
e){
                        e.printStackTrace();}
 
DOMSource source =newDOMSource(xmlDocument);
                    ffStream.close();
 
ByteArrayOutputStream bos =newByteArrayOutputStream();StreamResult result
=newStreamResult(bos);try{
                        transformer.transform(source, result);}
 
catch(TransformerException e){
                        e.printStackTrace();}b
 
yte[] array = bos.toByteArray();
                    outputStream.write(array);}});}finally{
            lock.release();
            s.close();
            ini.close();}try{FileInputStream input
=newFileInputStream(file);}catch(FileNotFoundException
e){Thread.sleep(5000);}catch(Exception e){
            e.printStackTrace();}
      session.transfer(flowFile1,REL_SUCCESS);



--
Sent from: http://apache-nifi-developer-list.39713.n7.nabble.com/

Re: nifi: How to update and trnaform xml file inside ExecuteScript processor

Posted by Joey Frazee <jo...@icloud.com>.
Sally, there are better ways to approach this:

- First, the default for transforming XML should be to use TransformXml [1] with an XSLT. It kinda looks like you’re also trying to extract some elements into attributes so I’d look at EvaluateXPath [2] too. Your flow would then look like [_] --> [TransformXml] --> [EvaluateXPath] --> [_].

- If you must use ExecuteScript, since you’re using Groovy, you don’t have to use the native Java XML APIs. Please have a look at Groovy’s documentation on processing XML [3] in particular XmlSlurper, DOMBuilder and the GPath expressions if you need them. I can’t really tell what you’re doing with the file locks, but I doubt they’re necessary.

Generally speaking, I think it’d be helpful to look at ExecuteScript as a last resort Swiss army knife for those situations where an existing processor doesn’t do what you need to do. We’re always adding more processors and functionality so you’d be surprised at how many things you can cover without having to drop down to ExecuteScript.

The time and effort to pore through every processor doc is often less than writing (and debugging) the code for ExecuteScript.

1. https://nifi.apache.org/docs/nifi-docs/components/org.apache.nifi/nifi-standard-nar/1.4.0/org.apache.nifi.processors.standard.TransformXml/index.html
2. https://nifi.apache.org/docs/nifi-docs/components/org.apache.nifi/nifi-standard-nar/1.4.0/org.apache.nifi.processors.standard.EvaluateXPath/index.html
3. http://groovy-lang.org/processing-xml.html

On Oct 14, 2017, 1:12 PM -0500, sally <sa...@gmail.com>, wrote:
>
> Question by sally sally 12 secs ago nifi-processorjavaapache-nifigroovy
> I want to read xml file from folder and i want to update it and make new
> flowfile(my code will be placed in nifi processor) which will containt this
> renewated data but i can't parse xml document properly i got error like
> this:org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot
> cast object 'com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl@181ae3f
>
> 1.what should i change?( except changing doc = builder.parse(inputStream)
> with doc=builder.parse(file) because i need to use string data for later
> processing)
>
> Another reason why i can't fulfill my task is that i can't make flowfile in
> which i would have placed all renewated xml data, for some reason i got
> empty flowfile even if i use this doc=builder.parse(file) i means use config
> file phisically( File file=new File('path')), what should i change to
> improve this case.
> if i use string content, should i use any alternative way to get xml tag
> data except using NodeList( i mean is it possible to use any better use
> case)? here is my groovy code:
>
> import org.apache.commons.io.IOUtils;
>
> import java.nio.charset.StandardCharsets;
>
> import java.io.RandomAccessFile;
>
> import java.nio.channels.FileLock;
>
> import java.io.BufferedReader;
>
> import org.apache.commons.io.IOUtils;
>
> import java.nio.charset.StandardCharsets;
>
> File file =newFile("C://Users//user//Desktop//2//conf.xml");
>
> String content ='';RandomAccessFile ini =newRandomAccessFile(file,"rws");
>
> FileLock lock = ini.getChannel().lock();BufferedReader s;
>
> DocumentBuilder dBuilder =null;Document doc=null;String
> start,startDate,endDate,runAs,makeVersion,patch;
>
> try{String sCurrentLine;
>
> s=newBufferedReader(Channels.newReader(ini.getChannel(),"UTF-8"));while((sCurrentLine
> = s.readLine())!=null){
> content+=sCurrentLine;}//make xml
> parsingDocumentBuilderFactory factory
> =DocumentBuilderFactory.newInstance();DocumentBuilder builder =
> factory.newDocumentBuilder();InputStream inputStream
> =newByteArrayInputStream(content.getBytes());
> doc = builder.parse(inputStream);NodeList nList =
> doc.getElementsByTagName("localAttributes");
>
> for(int temp =0; temp < nList.getLength(); temp++){Node nNode =
> nList.item(temp);
>
> if(nNode.getNodeType()==Node.ELEMENT_NODE){Element eElement =(Element)
> nNode;
> start =
> eElement.getElementsByTagName("start").item(0).getTextContent();
> startDate =
> eElement.getElementsByTagName("startDate").item(0).getTextContent();
> endDate =
> eElement.getElementsByTagName("endDate").item(0).getTextContent();
> patch =
> eElement.getElementsByTagName("patch").item(0).getTextContent();
> runAs =
> eElement.getElementsByTagName("runAs").item(0).getTextContent();
> makeVersion =
> eElement.getElementsByTagName("makeVersion").item(0).getTextContent();}}
> flowFile1 = session.putAttribute(flowFile1,"start", start);
> flowFile1 = session.putAttribute(flowFile1,"startDate",
> startDate);
> flowFile1 = session.putAttribute(flowFile1,"endDate", endDate);
> flowFile1 = session.putAttribute(flowFile1,"runAs", runAs);
> flowFile1 = session.putAttribute(flowFile1,"patch", patch);
> flowFile1 = session.putAttribute(flowFile1,"makeVersion",
> makeVersion);
>
> flowFile1 =
> session.putAttribute(flowFile1,"filename","conf.xml");
>
> DocumentBuilderFactory builderFactory =DocumentBuilderFactory.newInstance();
>
> DocumentBuilder builder = builderFactory.newDocumentBuilder();Document
> xmlDocument = builder.parse(inputStream);
>
> XPath xPath =XPathFactory.newInstance().newXPath();XPathExpression
> myNodeList =(XPathExpression) xPath.compile("/localAttributes");
>
> Node nodeGettingChanged =(Node)
> myNodeList.evaluate(xmlDocument,XPathConstants.NODE);NodeList childNodes =
> nodeGettingChanged.getChildNodes();for(int i =0; i !=
> childNodes.getLength();++i){Node child = childNodes.item(i);
>
> if(!(child
> instanceofElement))continue;if(child.getNodeName().equals("runAs"))
> child.getFirstChild().setNodeValue("false");}
>
> TransformerFactory transformerFactory
> =TransformerFactory.newInstance();Transformer transformer =null;
> transformer = transformerFactory.newTransformer();DOMSource
> source =newDOMSource(xmlDocument);StreamResult file1
> =newStreamResult(inputStream);
>
> try{
> transformer.transform(source,
> file1);}catch(TransformerException e){
> e.printStackTrace();}
> session.write(flowFile1,newStreamCallback(){@Overridepublicvoid
> process(InputStream inputStream,OutputStream outputStream)throwsIOException{
>
> TransformerFactory transformerFactory =TransformerFactory.newInstance();
>
> Transformer transformer =null;try{
> transformer =
> transformerFactory.newTransformer();}catch(TransformerConfigurationException
> e){
> e.printStackTrace();}
>
> DOMSource source =newDOMSource(xmlDocument);
> ffStream.close();
>
> ByteArrayOutputStream bos =newByteArrayOutputStream();StreamResult result
> =newStreamResult(bos);try{
> transformer.transform(source, result);}
>
> catch(TransformerException e){
> e.printStackTrace();}b
>
> yte[] array = bos.toByteArray();
> outputStream.write(array);}});}finally{
> lock.release();
> s.close();
> ini.close();}try{FileInputStream input
> =newFileInputStream(file);}catch(FileNotFoundException
> e){Thread.sleep(5000);}catch(Exception e){
> e.printStackTrace();}
> session.transfer(flowFile1,REL_SUCCESS);
>
>
>
> --
> Sent from: http://apache-nifi-developer-list.39713.n7.nabble.com/