Options

Processing CDATA with DotNet variables in NAV2013

jeighsohnjeighsohn Member Posts: 12
Hello

I've been searching the forum all afternoon reading about how I can handle CDATA in an XML response from a web service I am consuming in NAV2013 (yes, I know, it's an ancient version, lol).

I've found some threads that show how to handle it with XMLDOM, but I prefer to handle with system.xml due to the msxml.dll being deprecated a long time ago and I'm having a really hard time trying to find any code examples that actually apply to me. I've seen some more recent code that uses functions not available to me in NAV2013, and I've seen some sample code with no clear indication of what the variables are. I've tried to convert some of the XMLDOM examples to system.xml variables, but I'm running into issues with unrecognized syntax (cannot compile or if I do, I get an error immediately upon trying to run the code).

Does anyone have an example of how I can parse a block of CDATA in NAV2013 using DotNet System.xml variables?

Best Answers

  • Options
    ftorneroftornero Member Posts: 522
    Answer ✓
    Hello @jeighsohn

    Wiht this example you must to read the <IMTimeStampSearchRedsult> tag and assign the result to a new Xml document and parse this new one.

    The XMLDoc variable must be the response XML and with the code below
      IF FindNode2(XMLDoc, 'IMTimeStampSearchResult', Node) THEN BEGIN
        TextoCDATA := Node.InnerText;
        XMLDoc.LoadXml(TextoCDATA);
      END;
    

    in that variable you get the Xml inside the CDATA part.

    p4cdg4bit3d9.png

    These are the variables:
    Name	DataType	Subtype	Length
    XMLDoc	DotNet	System.Xml.XmlDocument.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'	
    Node	DotNet	System.Xml.XmlNode.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'	
    TextoCDATA	Text		
    

    The FindNode2 function is this one:
    FindNode2(XMLRootNode : DotNet "System.Xml.XmlNode";NodeName : Text;VAR FoundXMLNode : DotNet "System.Xml.XmlNode") : Boolean
      FoundXMLNode := XMLRootNode.SelectSingleNode(STRSUBSTNO('//*[local-name()="%1"]', NodeName));  
      IF ISNULL(FoundXMLNode) THEN
        EXIT(FALSE)
      ELSE
        EXIT(TRUE); 
    

    Regards
  • Options
    ftorneroftornero Member Posts: 522
    Answer ✓
    Hello @jeighsohn

    Yes the problem with your hard-coded calls are the namespaces.

    But the function FindNode2 works fine, did you created the function ?

    Could you post the complete code that are using ?

    Regards.

Answers

  • Options
    ftorneroftornero Member Posts: 522
    Hello @jeighsohn,

    You don't need any special function to deal with CDATA, just select the node with the CDATA and assign its InnerText value to a Text variable.

    Regards.
  • Options
    jeighsohnjeighsohn Member Posts: 12
    Thank you for the reply...

    It is many nodes within the CDATA tag. The response could include a set of elements for dozens of entities (Customers or Vendors) per our Restricted Party Screening process I've been tasked with building. The CDATA tag seems to make it so NAV2013 can't see any of the elements within the CDATA tag (the open and close tags are seen as other characters). NAV can't seem to find the nodes I actually need to read that are within the CDATA section.
  • Options
    ftorneroftornero Member Posts: 522
    Hello @jeighsohn,

    Ussually inside the CDTA there is another XML structure, so you need to load previous Text variable into a new XML and parse this one.

    If you could post an example of the response I could be more specific.

    Regards
  • Options
    jeighsohnjeighsohn Member Posts: 12
    Hi! Sorry for the late reply. I was out of the office for the holiday.

    Here is the general structure of the reply. The SHresult can be one or many.
    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
    <IMTimeStampSearchResponse
    xmlns="http://eim.visualcompliance.com/RPSService/2016/11">
    <IMTimeStampSearchResult>
    <![CDATA[<SH>
    <SHTime>
    <SHTimeFrom>2018-07-24T00:00:00</SHTimeFrom>
    <SHTimeTo>2018-07-25T14:19:11</SHTimeTo>
    </SHTime>
    <SHresults>
    <SHresult id="267063362374320">
    <SHrevsecno>06G8M</SHrevsecno>
    <SHownersecno>06G8M</SHownersecno>
    <SHrevlogin>EXT0011</SHrevlogin>
    <SHrevdiv>RPS TESTING PARAMETERS</SHrevdiv>
    <SHstatus>DS New</SHstatus>
    <SHrevdate>07-24-2018 17:39:06</SHrevdate>
    <SHname></SHname>
    <SHcompany>Winston</SHcompany>
    <SHoptid></SHoptid>
    </SHresult>
    </SHresults>
    </SH>]]>
    </IMTimeStampSearchResult>
    </IMTimeStampSearchResponse>
    </s:Body>
    </s:Envelope>
    
  • Options
    ftorneroftornero Member Posts: 522
    Answer ✓
    Hello @jeighsohn

    Wiht this example you must to read the <IMTimeStampSearchRedsult> tag and assign the result to a new Xml document and parse this new one.

    The XMLDoc variable must be the response XML and with the code below
      IF FindNode2(XMLDoc, 'IMTimeStampSearchResult', Node) THEN BEGIN
        TextoCDATA := Node.InnerText;
        XMLDoc.LoadXml(TextoCDATA);
      END;
    

    in that variable you get the Xml inside the CDATA part.

    p4cdg4bit3d9.png

    These are the variables:
    Name	DataType	Subtype	Length
    XMLDoc	DotNet	System.Xml.XmlDocument.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'	
    Node	DotNet	System.Xml.XmlNode.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'	
    TextoCDATA	Text		
    

    The FindNode2 function is this one:
    FindNode2(XMLRootNode : DotNet "System.Xml.XmlNode";NodeName : Text;VAR FoundXMLNode : DotNet "System.Xml.XmlNode") : Boolean
      FoundXMLNode := XMLRootNode.SelectSingleNode(STRSUBSTNO('//*[local-name()="%1"]', NodeName));  
      IF ISNULL(FoundXMLNode) THEN
        EXIT(FALSE)
      ELSE
        EXIT(TRUE); 
    

    Regards
  • Options
    jeighsohnjeighsohn Member Posts: 12
    Thank you! This was tremendously helpful.

    One more very dumb question from me - when Finding the node in FindNode2, is the base string being used in the string substitution supposed to be specific to my file, or directly as shown in your example? When I run the code as shown in your example, it never finds the node IMTimeStampSearchResult (always exits FALSE).
  • Options
    ftorneroftornero Member Posts: 522
    Hello @jeighsohn,

    It's de name of the tag with the CDATA value, in your example is IMTimeStampSearchResult:

    zasvka8ueao6.png

    REgards
  • Options
    jeighsohnjeighsohn Member Posts: 12
    @ftornero
    Thanks, I understand that part, but not the syntax of the SelectSingleNode string parameter.

    In your code example, you are passing the nodename into //*[local-name()="%1"]. This always results in a null node for me and the function returns False.
    FoundXMLNode := XMLRootNode.SelectSingleNode(STRSUBSTNO('//*[local-name()="%1"]',NodeName));
    

    I also tried other hard-coded syntax iterations (just to test) like:
    FoundXMLNode := XMLRootNode.SelectSingleNode('//*["IMTimeStampSearchResult"]');
    -or-
    FoundXMLNode := XMLRootNode.SelectSingleNode('//"IMTimeStampSearchResult"');
    -or-
    FoundXMLNode := XMLRootNode.SelectSingleNode('//IMTimeStampSearchResult');
    -or-
    FoundXMLNode := XMLRootNode.SelectSingleNode('IMTimeStampSearchResult');
    -or-
    FoundXMLNode := XMLRootNode.SelectSingleNode('//Envelope/Body/IMTimeStampSearchResponse/IMTimeStampSearchResult');

    and all of these fail as well.

    Is the namespace the problem? Do I need to remove that first, then try to get at the CDATA?
  • Options
    ftorneroftornero Member Posts: 522
    Answer ✓
    Hello @jeighsohn

    Yes the problem with your hard-coded calls are the namespaces.

    But the function FindNode2 works fine, did you created the function ?

    Could you post the complete code that are using ?

    Regards.
  • Options
    jeighsohnjeighsohn Member Posts: 12
    @ftornero

    Thanks to your wise request to see my code, when I went to copy/paste it here, I noticed an oversight in one missing line in my logic that was responsible for all of my problems. Thank you!! I am now seeing the contents of the CDATA tags. My next step will be to figure out how to handle that data, but your assistance was truly invaluable. Thank you!
Sign In or Register to comment.