Hoppa till huvudinnehållet

Use Xml in a workflow

Kommentarer

9 kommentarer

  • Berend Veldkamp

    Actually, it seems that the exception is raised when instantiating the XmlDocument (which makes more sense I guess). However, this doesn't bring me any closer to a solution, so if anyone has an idea?

     

    Now that I just wrote this, it occurred to me that the WebRequest activity may be executed on the server, is that correct? If so, the xmldocument would have to be transported to the client somehow, requiring a serializable type, which XmlDocument is not.

    So, what would be the best approach to solve this, can I parse the xml on the server, and send only a list of [some object] to the client?

    0
  • Ryan Cooney

    Yes, the WebRequest activity runs on the server.

    Presumably you have a custom client side activity that you want to pass the "stuff" that is in the XML document to. You've got a couple options:

    • Send the XML to the client activity as text and let the client activity parse it there. You'll need to encode the byte array as text. Something like: System.Text.UTF8Encoding.UTF8.GetString(bytes); should work.
    • Deserialize the XML into your business objects on the server and send them to the client activity. Note that the objects must themselves be serializable and the same types must exist on both the server and client for this option.

    --Ryan

    0
  • Berend Veldkamp

    Ryan,

    Thanks for your reply. 

     

    How do I parse the xml on the client, is it possible to use an XmlDocument or XDocument there? Or do i need some nifty regular expressions to do that? I already had the UTF8.GetString(), followed by an AssignTask with <tt>doc=NewXmlDocument()</tt> and then doc.LoadXml(xml), but that doesn't work.

    BTW, what I'm doing is querying a geocoding service that uses the OpenGIS ols format. The result is a list of 0 or more locations containing all kinds of optional fields (placename, street, zip, etc), and an XY coordinate.

     

    0
  • Ryan Cooney

    You'll need to use XDocument in Silverlight.

    I hope I haven't sent you off track here. The only reason to have the client activity do the parsing would be if that very same client activity were going to process and use the results (maybe to update the map). If you plan to use the results to call subsequent activities we'll probably want to do the parsing on the server.

    Can you give me a big picture overview of your workflow? 

    1. Make a request to the geocode service.
    2. Parse the XML into geocode result objects.
    3. Do something with the results. What do you plan to do here? Zoom to the results, highlight the results, select the results?

    --Ryan

    0
  • Berend Veldkamp

    My workflow is really very straightforward:

    1. User makes a geocoding request
    2. Geocoding service returns xml, containing a list of matches
    3. User picks one
    4. Map zooms to selected location

     

    How do I specify that an XDocument lives on the client? Right now, I can create an xdoc using an Assign with xDoc=XDocument.Parse(xml), but it seems to be created on the server, because as soon as I try to do something with it (e.g. Alert(xDoc.ToString())), it has to be transfered to the client, and I get an exception.

     

    Here's my workflow reduced to it's basics:

    <Activitymc:Ignorable="sap" x:Class="{x:Null}" sap:VirtualizedContainerService.HintSize="401,905" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:eac="clr-namespace:ESRI.ArcGIS.Client;assembly=ESRI.ArcGIS.Client" xmlns:eacg="clr-namespace:ESRI.ArcGIS.Client.Geometry;assembly=ESRI.ArcGIS.Client" xmlns:eact="clr-namespace:ESRI.ArcGIS.Client.Tasks;assembly=ESRI.ArcGIS.Client" xmlns:esri="http://schemas.esri.com/arcgis/client/2009" xmlns:gfc="clr-namespace:Geocortex.Forms.Client;assembly=Geocortex.EssentialsWpfApi" xmlns:gr="clr-namespace:Geocortex.Reporting;assembly=Geocortex.Reporting" xmlns:gwa="clr-namespace:Geocortex.Workflow.Activities;assembly=Geocortex.Workflow" xmlns:gwa1="clr-namespace:Geocortex.Workflow.Activities;assembly=Geocortex.Workflow.Activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=System.Core" xmlns:s1="clr-namespace:System;assembly=System" xmlns:s2="clr-namespace:System;assembly=mscorlib" xmlns:s3="clr-namespace:System;assembly=System.Numerics" xmlns:s4="clr-namespace:System;assembly=System.ServiceModel" xmlns:sa="clr-namespace:System.Activities;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sg="clr-namespace:System.Globalization;assembly=mscorlib" xmlns:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:str="clr-namespace:System.Text.RegularExpressions;assembly=System" xmlns:sx="clr-namespace:System.Xml;assembly=System.Runtime.Serialization" xmlns:sx1="clr-namespace:System.Xml;assembly=System.Data" xmlns:sx2="clr-namespace:System.Xml;assembly=System.Xml" xmlns:sxl="clr-namespace:System.Xml.Linq;assembly=System.Xml.Linq" xmlns:sxx="clr-namespace:System.Xml.XPath;assembly=System.Xml" xmlns:sxx1="clr-namespace:System.Xml.XPath;assembly=System.Xml.Linq" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><p> </p>   <Sequence sap:VirtualizedContainerService.HintSize="361,574" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces"><p> </p>     <Sequence.Variables><p> </p>       <Variable x:TypeArguments="s2:Byte[]" Name="searchResult" /><p> </p>       <Variable x:TypeArguments="sxl:XDocument" Name="xDoc" /><p> </p>       <Variable x:TypeArguments="x:String" Name="xml" /><p> </p>     </Sequence.Variables><p> </p>     <sap:WorkflowViewStateService.ViewState><p> </p>       <scg:Dictionary x:TypeArguments="x:String, x:Object"><p> </p>         <x:Boolean x:Key="IsExpanded">True</x:Boolean><p> </p>       </scg:Dictionary><p> </p>     </sap:WorkflowViewStateService.ViewState><p> </p>     <gwa1:WebRequest Headers="{x:Null}" ResponseHeaders="{x:Null}" sap:VirtualizedContainerService.HintSize="339,128" Method="GET" Result="[searchResult]" Uri="http://acceptatie.geodata.nationaalgeoregister.nl/geocoder/Geocoder"><p> </p>       <gwa1:WebRequest.Values><p> </p>         <gwa:ArgumentWrapper x:TypeArguments="InArgument(x:String)" Argument="Amsterdam" IsRequired="False" Name="zoekterm" /><p> </p>       </gwa1:WebRequest.Values><p> </p>     </gwa1:WebRequest><p> </p>     <Assign sap:VirtualizedContainerService.HintSize="339,58"><p> </p>       <Assign.To><p> </p>         <OutArgument x:TypeArguments="x:String">[xml]</OutArgument><p> </p>       </Assign.To><p> </p>       <Assign.Value><p> </p>         <InArgument x:TypeArguments="x:String">[System.Text.Encoding.UTF8.GetString(searchResult)]</InArgument><p> </p>       </Assign.Value><p> </p>     </Assign><p> </p>     <Assign sap:VirtualizedContainerService.HintSize="339,58"><p> </p>       <Assign.To><p> </p>         <OutArgument x:TypeArguments="sxl:XDocument">[xDoc]</OutArgument><p> </p>       </Assign.To><p> </p>       <Assign.Value><p> </p>         <InArgument x:TypeArguments="sxl:XDocument">[XDocument.Parse(xml)]</InArgument><p> </p>       </Assign.Value><p> </p>     </Assign><p> </p>     <gwa1:Alert sap:VirtualizedContainerService.HintSize="339,86" Text="[xDoc.ToString()]" Title="xDoc" /><p> </p>   </Sequence><p> </p> </Activity>

    0
  • Ryan Cooney

    Berend,

    You don't actually specify that an object lives on the client or server. When an Activity runs it will either run on the client or on the server. When it is a client activity the input values for the activity and the current workflow state are sent to the client. Nothing remains on the server. The client performs the execution logic of the activity and the outputs values of the activity and the workflow state are sent back to the server. Nothing remains on the client.

    The workflow state that is transferred between client and server contains the serialized values of all the variables that are currently in scope. This is what is happening in your workflow. All of your activities run on the server except the Alert. The input Text argument of the Alert is just a string so it serializes fine; however, all of your other variables are still in scope so they have to be serialized too. Since the XmlDocument is still in scope and not serializable it fails. If you look at the Variables tab in Designer you can see the Scope of each of them. 

    I've modified the scope of your variables using a new Sequence activity: (https://data.latitudegeo.com/community/userfiles/1725/xmlinaworkflow.zip) xmlinaworkflow.zip . You should be able to do all of your XML parsing logic inside the "XmlSequence" (don't put any client activities in this sequence). When the XmlSequence completes all of the variables in it go out of scope. Now when the Alert activity runs (on the client) the XmlDocument is no longer part of the workflow state.

    --Ryan

     

    0
  • Berend Veldkamp

    Ryan,

    Thanks so much for time.

    In the meantime, I also watched the video about building custom activities (http://data1.latitudegeo.com/supportdownload.aspx?file=Webinars\Creating_Custom_Activities.wmv). I now have a server side activity that does all the hard work, and only a sends a list of DataItems to the client.

    I'll have a look at your approach too, I'm sure I'll learn something from it.

    Berend

    0
  • Permanently deleted user

    Ryan,

    I have successfully used the xmlinaworkflow.xaml that you posted in my own workflow to search for an address in my county and perform a web request to the Zillow API to get data on that address. The workflow is working great and I can see in the alert activity that lots of data in xml format is being returned. Ideally, I would like to be able to display the xml as formatted html in the viewer or generate a report that has the xml in a readable format. However, I am not a seasoned programmer so my question would be what can I do in this workflow to accomplish this? Here is what the xml looks like in the alert when I perform a web request to the Zillow API:

    <?xml version="1.0" encoding="utf-8"?><SearchResults:searchresults xsi:schemaLocation="http://www.zillow.com/static/xsd/SearchResults.xsd http://www.zillowstatic.com/vstatic/b35efa7/static/xsd/SearchResults.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SearchResults="http://www.zillow.com/static/xsd/SearchResults.xsd"><request><address>304 Hearthstone Ct</address><citystatezip>Woodstock GA30189</citystatezip></request><message><text>Request successfully processed</text><code>0</code></message><response><results><result><zpid>51106110</zpid><links><homedetails>http://www.zillow.com/homedetails/304-Hearthstone-Ct-Woodstock-GA-30189/51106110_zpid/</homedetails><graphsanddata>http://www.zillow.com/homedetails/304-Hearthstone-Ct-Woodstock-GA-30189/51106110_zpid/#charts-and-data</graphsanddata><mapthishome>http://www.zillow.com/homes/51106110_zpid/</mapthishome><comparables>http://www.zillow.com/homes/comps/51106110_zpid/</comparables></links><address><street>304 Hearthstone Ct</street><zipcode>30189</zipcode><city>Woodstock</city><state>GA</state><latitude>34.095832</latitude><longitude>-84.547476</longitude></address><FIPScounty>13057</FIPScounty><useCode>SingleFamily</useCode><taxAssessmentYear>2014</taxAssessmentYear><taxAssessment>145100.0</taxAssessment><yearBuilt>1994</yearBuilt><finishedSqFt>1500</finishedSqFt><bathrooms>2.0</bathrooms><bedrooms>3</bedrooms><lastSoldDate>02/28/2000</lastSoldDate><lastSoldPrice currency="USD">139900</lastSoldPrice><zestimate><amount currency="USD">159477</amount><last-updated>08/09/2015</last-updated><oneWeekChange deprecated="true"></oneWeekChange><valueChange duration="30" currency="USD">3021</valueChange><valuationRange><low currency="USD">146719</low><high currency="USD">170640</high></valuationRange><percentile>0</percentile></zestimate><localRealEstate><region name="Woodstock" id="48573" type="city"><zindexValue>169,600</zindexValue><links><overview>http://www.zillow.com/local-info/GA-Woodstock/r_48573/</overview><forSaleByOwner>http://www.zillow.com/woodstock-ga/fsbo/</forSaleByOwner><forSale>http://www.zillow.com/woodstock-ga/</forSale></links></region></localRealEstate></result></results></response></SearchResults:searchresults><!-- H:003 T:18ms S:1154 R:Wed Aug 12 07:32:23 PDT 2015 B:4.0.18256-release_20150805-admiral-ackbar.36e8600~candidate.41df277 -->

    As you can see there are several fields with data and hyperlinks so again, I would like to be able to display this to our users as a styled document of some sort whether it be in a display form in the workflow or in a report. Any examples or advice you could provide would be greatly appreciated.

    0
  • Permanently deleted user

    Thanks Ryan. I'll put in a support ticket. 

    0

Du måste logga in om du vill lämna en kommentar.