Support Questions
Find answers, ask questions, and share your expertise

Preserving the parent element in XML document with XMLReader

Explorer

When using the XMLReader service, how do you retain the outermost parent element of an XML document so when I convert it to JSON I have the outermost element in the JSON version too?

 

For example, given the following XML document how do I capture the "<a>" element rather than just the "<b>" element?  

 

<a>
<b>45</b>
</a>

 

What I want:

{"a": {"b":45}}

 

What I get:

{"b":45}

 

2 ACCEPTED SOLUTIONS

Master Collaborator

@ChuckE ,

 

You can use a JoltTransformRecord processor to perform the conversion to JSON and, at the same time, add the root node back to it.

 

araujo_0-1659503928628.png

The JOLT specification I used is this:

{
  "*": "a.&"
}

 

Cheers,

André

 

 

--
Was your question answered? Please take some time to click on "Accept as Solution" below this post.
If you find a reply useful, say thanks by clicking on the thumbs up button.

View solution in original post

Explorer

I've since discovered a super easy way to resolve this.  Simply using the XMLRecordSetWriter does EXACTLY what I was looking for.  

View solution in original post

11 REPLIES 11

Expert Contributor

Hi,

Im not sure this can be fixed by changing some configuration on what you have wither on the processor or the service level. Since the root element is not considered in the conversion from xml to Json, as workaround you can surround your xml with arbitrary root element with the ReplaceText Processor before the ConvertRecrod Processor:

SAMSAL_0-1659116224899.png

  •   Search Value: (?s)(^.*$)
  •   Replacement Value: <root>$1</root>
  •   Evaluation Mode: Entire Text

 This will output the following xml:

<root>n<a>
  <b>45</b>
</a>
n</root>

And After ConvertRecord Prceossor :

{"a": {"b":45}}

Hope that helps. If it does, please Accept Solution.

Thanks

 

 

 

 

 

 

 

Explorer

Thank you SAMSL for your response.  In the interest of scalability I was trying to avoid performing text manipulations.  I ultimately decided to go with an XSLT transform since this processor is optimized for performing these types of operations, making it more scalable.  I wanted to verify there wasn't an option within the XMLReader that I was missing, but it seems not.  

On a side note, as an intellectual curiosity I also tried using the QueryRecord processor to see if I could select the outermost element in a query and slap wrapper text around it.  But it seems there is no way to perform this task with an XMLReader because it can't discern the schema of the data, so "select * from flowfile" is the only thing that works apparently.  

Master Collaborator

@ChuckE 

 

Do your XML messages conform to defined a schema?

 

Cheers,

André

--
Was your question answered? Please take some time to click on "Accept as Solution" below this post.
If you find a reply useful, say thanks by clicking on the thumbs up button.

Explorer

Yes, I validate the incoming xml with a strongly typed xsd.  

Master Collaborator

@ChuckE ,

 

You can use a JoltTransformRecord processor to perform the conversion to JSON and, at the same time, add the root node back to it.

 

araujo_0-1659503928628.png

The JOLT specification I used is this:

{
  "*": "a.&"
}

 

Cheers,

André

 

 

--
Was your question answered? Please take some time to click on "Accept as Solution" below this post.
If you find a reply useful, say thanks by clicking on the thumbs up button.

Explorer

This seems like a good idea.  I'll give this a try and test the performance against the XSLT transform.  I've never used the JOLT processors before so this will be a good opportunity to experiment with one.  Thanks for the idea.

Master Collaborator

I'm also curious about the performance difference. If you could report your results here, I'd appreciate!

 

Cheers,

André

 

--
Was your question answered? Please take some time to click on "Accept as Solution" below this post.
If you find a reply useful, say thanks by clicking on the thumbs up button.

Explorer

I've since discovered a super easy way to resolve this.  Simply using the XMLRecordSetWriter does EXACTLY what I was looking for.  

Expert Contributor

Can you explain how did you resolve it with XMLRecrodSetWriter? Thanks

Explorer

I create an XMLRecordSetWriter in the Controller Services, then using a ConvertRecord processor I'm able to read the xml record and then immediately write it out with a new root tag, which I can then pass to my next processor.  I discovered this when I was reading the documentation for the XMLRecordSetWriter.  Very first line in the documentation. 😃

https://nifi.apache.org/docs/nifi-docs/components/org.apache.nifi/nifi-record-serialization-services...

 

Master Collaborator

Ahh! Good catch, @ChuckE !! So simple!

araujo_0-1659580409302.png

 

--
Was your question answered? Please take some time to click on "Accept as Solution" below this post.
If you find a reply useful, say thanks by clicking on the thumbs up button.
Take a Tour of the Community
Don't have an account?
Your experience may be limited. Sign in to explore more.