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.

Reply
  • 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.

Children
  • 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 Acacio Barrado
    The input for the expression should be the document ID and not the document itself

    So just FYI... in almost all cases, there will be no difference, as the "document itself" (assuming you're referring to an object of type "Appian Document") is really just the document's ID, and use cases that require the ID will almost always typecast the document down to its integer ID if necessary.

  • 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 Mike,

    I totally agree with you,

    Thank you,

    Acacio B.

  • 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.