Reading an XML file into an Interface

Hi I have a need to be able to select an XML file, and use fields in it to populate an interface.


At the moment I have a simpe interface with a File Upload and a Rule Input of xmlData (Document) which the file upload saves to.

I am then kicking off a process model on submit which runs a script task.

I have activity class parameters for the fields I want and am running the following script on each one

=xpathdocument(pv!xmlFile,"/Document/Fields/Field[@Name='Department']/@Value")
Currently I just get an error on the process model when I debug:
Script Task An error occurred while evaluating expression: =xpathdocument(pv!xmlFile,"/Document/Fields/Field[@Name='Department']/@Value") (Expression evaluation error at function 'xpathdocument': An error occurred while trying to parse the XML stream.) (Data Inputs)

Does anyone know what the error is more specifically?  Am I on the right lines or is there a better way of doing this? 

  Discussion posts and replies are publicly visible

Parents
  • Hi David,

    Few recommendations that I could give to you:

    • The input for the expression should be the document ID and not the document itself
    • Check in your xml file if you have namespaces defined, in case you need, it needs to be a parameter in the expression
    • If you are trying to retrieve just the text out of one xml tag try to use “/text()” instead “/@value”

    I’m adding a sample code below, in this example only the text of the tag "content" is retrieved:

    xpathdocument(
      docId: 9999,
      expression: "/a:document/data/body/item/content/text()",
      /*sample namespace prefix just add if your input xml has ns*/
      prefix: "a:http://www.appian.com/ae/types/2009"
    )

    Regards,

    Acacio Barrado.

  • Hi Acacio

    How would I find the DocumentID?  This is my interface - I assume it is the 47259 stored in the rule input before the filename?  What would be the best way of grabbing this in the process model?

    Also, where do I check for if the xml has namespace?

    This is the document properties of one I uploaded

    Thanks
    David

  • 0
    Certified Lead Developer
    in reply to David Craven
    How would I find the DocumentID? 

    Your assumptions are correct, as long as you account for needing to submit a form prior to accessing a document's properties (which i believe you're already doing correctly).  If needed, you can always typecast a document object directly to its ID by, among other things, passing the document object through the "toInteger()" function.  As I noted in my prior reply though, in almost all cases it won't make any difference, as integer and document objects will almost seamlessly cross-typecast as needed depending on the service in question.

  • Hi David,

    As pointed out by Mike, you don’t need to worry about the document Id, looking into the documentation for the function “xpathdocument”, we can see that the parameter docId is Any Type, and it would accept both, document or document Id. Therefore, there was nothing wrong in your implementation.

    Documentation Reference:

    docId (Any Type): Xml Document id or Content Item (Document).

    About the name space, it is normally defined in the root node of the XML, it can be also defined direct in one of the XML nodes, so you need to check it in your XML file. An easy way to check is looking for prefixes in the child nodes or in the root node.

    I’m adding a sample XML from w3schools, in it you will be able to see two name spaces with different prefix (h and f), so lets say that you want to return the child <f:name> under the node <f:table>, so you would need to add in the function parameter prefix, something like that:

    prefix: "f:https://www.w3schools.com/furniture"

    <root xmlns:h="http://www.w3.org/TR/html4/" xmlns:f="https://www.w3schools.com/furniture">
    	<h:table>
    		<h:tr>
    			<h:td>Apples</h:td>
    			<h:td>Bananas</h:td>
    		</h:tr>
    	</h:table>
    	<f:table>
    		<f:name>Coffee Table</f:name>
    		<f:width>80</f:width>
    		<f:length>120</f:length>
    	</f:table>
    </root>

    I hope this helps you.

  • Ok thanks all 

    I've attached a copy of the sample XML I am using - dont think there is a namespace?

    Currently the field data I am trying to grab from the XML is:

            <Field Name="Company" Value="Park Mill"/>

    and this is the expression in the Process Model Script Task

    =xpathdocument(
    docID: pv!xmlFile,
    expression: "/Document/Fields/Field[@Name='Company']/@Value"
    )

    Also, I just wondered what difference it would make if the XML fields were in the following format:

        <Company>Parkmill</Company>

    Would the expression need to be different?

    <Document Classification="CustomerSupport" URN="\\stsrvpfs01\autostore\AFS\SmartView\FixForward\Test\9999_CustomerSupport_GeneralCorrespondence_20200320_154654.7.pdf">
    <Pages>
        <Page Name="File1" Value="\\stsrvpfs01\autostore\AFS\SmartView\FixForward\Test\9999_CustomerSupport_GeneralCorrespondence_20200320_154654.7.pdf"/>
      </Pages>
      <Fields>
    
           	<Field Name="Organisation" Value="Adare SEC"/>
           	<Field Name="Company" Value="Park Mill"/>
           	<Field Name="Department" Value="Customer Support"/>
    	<Field Name="DocumentType" Value="General Correspondence"/>
    
    	<Field Name="FileName" Value="GeneralCorrespondence1234.pdf"/>
           	<Field Name="NumberOfImages" Value="2"/>
           	<Field Name="BoxID" Value="12345"/>
         	<Field Name="ScannedDate" Value="2020-03-20 15:50:10.000"/>
    	<Field Name="BatchID" Value="9999_CustomerSupport_GeneralCorrespondence_20200320_154654"/>
    
    	<Field Name="AccountNumber" Value="999999999"/> 
           	<Field Name="ApplicationNumber" Value="AP99999"/>
           	<Field Name="Surname" Value="Sample"/>
           	<Field Name="Forename" Value="A"/>
           	<Field Name="Initials" Value="J"/>
           	<Field Name="AddressLine1" Value="21 Sample Street"/>
           	<Field Name="AddressLine2" Value="Sample Town"/>
           	<Field Name="AddressLine3" Value="Sample City"/>
           	<Field Name="AddressLine4" Value=""/>
           	<Field Name="AddressLine5" Value=""/>
           	<Field Name="PostCode" Value="AB1 1AB"/>
     	<Field Name="ReferenceNumbers" Value=""/>
          	<Field Name="PoliceRef" Value=""/>
           	<Field Name="FSComplaintRef" Value=""/>
           	<Field Name="DateOfBirth" Value=""/>
    	<Field Name="AccountNumber2" Value=""/>
    
           	<Field Name="ExceptionFlagged" Value="False"/>
           	<Field Name="ExceptionConfirmed" Value="False"/>
       	<Field Name="ManualCaptureIndicator" Value="False"/>
           	<Field Name="PoorQualityOriginal" Value="False"/>
           	<Field Name="OperatorName" Value="Nathaniel.Hine"/>     
         	
      </Fields>
    </Document>

  • Hi David,

    Yes, there is a big difference in relation to the format of your XML.

    In the current format as you sent in your example, the data that you are trying to retrieve is stored in one of the attributes from of the field called Field. This field is generated multiple times in your XML and the only difference between them is the values in the attributes (Field Name and value). It is possible to get the value that you are looking for, by AFAIK, you would need to rely on indexes, I’m attaching a code below where that you can use to get the Company value:

    xpathdocument(
      docId: YOURDOC,
      expression: "Document/Fields/Field[2]/@Value" 
    )

    On the other hand, using the second format that you proposed you could easily get the value from company without need to rely on index. I’m attaching a code example below:

    xpathdocument(
      docId: YOURDOC,
      expression: "Document/Fields/Company/text()" 
    )

    Regards

    Acacio B.

  • Hi Acacio

    Thanks for that.  I've tried using both snippets of your code (replacing YOURDOC with pv!xmlFile, with each XML file but get the same error each time

    Not sure where it is going wrong, have tried putting a tointeger() around the pv!xmlFile just in case

    David

  • Just wondering - when I test the interface it is passing in the doc id and name into the rule input

    BUt in the Process Model where it is passed into a parameter it is just the name

    Would that be effecting it?

  • Hey David,

    For the XML that you post as example the first code that I sent in my previous answer should work, as I tested it in my local environment.

    In order to speed up your tests you could upload a file to Appian and test it in an expression rule, just past the code that I sent and change the docId, in case it is working in the expression and failing in your process model you need to analyse in detail the steps in your PM.

    Let me know,

    Regards.

    Acacio B.

  • HI Acacio

    Your right - I got the first line of code to work within an expression rule, so Im just going wrong somewhere else in the process model.


    Regarding the second method, that wouldn't work, although the structure of the XML file is slightly different - Ive tried replacing fields with Root and Original Variables - if you could let me know the correct syntax for it that would be great (Ive attached it here)

    <?xml version="1.0" encoding="UTF-8"?>
    <Root>
      <Original Variables>
        <CardholderElement>Carolina Kenny</CardholderElement>
        <Card NumberElement>449450294</Card NumberElement>
      </Original Variables>
      <Scanning/>
      <Queue Info>
        <Company>Parkmill</Company>
      </Queue Info>
    </Root>
    

  • Hi David,

    The xml example that you provided is not a valid xml, the main problem is that you cannot have a XML tag name with spaces, otherwise the second word would be interpreted as an attribute. 

    I edited your example in order to make the XML valid, and from there you can adjust to your process. Please find the valid xml in the code below:

    <?xml version="1.0" encoding="UTF-8"?>
    <Root>
    	<OriginalVariables>
    		<CardholderElement>Carolina Kenny</CardholderElement>
    		<CardNumberElement>449450294</CardNumberElement>
    	</OriginalVariables>
    	<Scanning/>
    	<QueueInfo>
    		<Company>Parkmill</Company>
    	</QueueInfo>
    </Root>

    Below is the code example for you get the company value:

    xpathdocument(
      docId: YOURDOC,
      expression: "Root/QueueInfo/Company/text()" 
    )

    In case these responses were helpful don't forget to mark the question as answered as it can also help other that are facing similar issues.

    Regards,

    Acacio B.

Reply
  • Hi David,

    The xml example that you provided is not a valid xml, the main problem is that you cannot have a XML tag name with spaces, otherwise the second word would be interpreted as an attribute. 

    I edited your example in order to make the XML valid, and from there you can adjust to your process. Please find the valid xml in the code below:

    <?xml version="1.0" encoding="UTF-8"?>
    <Root>
    	<OriginalVariables>
    		<CardholderElement>Carolina Kenny</CardholderElement>
    		<CardNumberElement>449450294</CardNumberElement>
    	</OriginalVariables>
    	<Scanning/>
    	<QueueInfo>
    		<Company>Parkmill</Company>
    	</QueueInfo>
    </Root>

    Below is the code example for you get the company value:

    xpathdocument(
      docId: YOURDOC,
      expression: "Root/QueueInfo/Company/text()" 
    )

    In case these responses were helpful don't forget to mark the question as answered as it can also help other that are facing similar issues.

    Regards,

    Acacio B.

Children
No Data