Jump to content
View in the app

A better way to browse. Learn more.

FMForums.com

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Parsing XML with multiple array's and attributes

Featured Replies

I am currently using the ExtraData CF found on http://www.fmfunctions.com/fid/202

 

This has worked very well for me for some time, however the data I am parsing has now changed to include the same attribute across multiple arrays of data.  Does anybody know of a custom function that will allow me to target a specific array's attributes?

Not sure what an "array" means in the context of XML. However, I am quite sure that parsing XML inside Filemaker is not the best way to consume it (to put it mildly). Why don't you import the source XML data using a custom XSLT stylesheet instead?

  • Author

Sorry, I'm not sure what the correct term as it relates to XML would be.    After a little searching, it appears as if the most appropriate terminology would be "parent" and "child" attributes.

 

I'm working with the Google Maps API to geocode and calculate distance (as the crow flies) between two points.  This is the XML structure that the Google API says an addresses will be returned as:

<?xml version="1.0" encoding="UTF-8"?>
<GeocodeResponse>
 <status>OK</status>
 <result>
  <type>street_address</type>
  <formatted_address><Address here></formatted_address>
  <address_component>
   <long_name>110</long_name>
   <short_name>110</short_name>
   <type>street_number</type>
  </address_component>
  <address_component>
   <long_name>Oxmoor Court</long_name>
   <short_name>Oxmoor Ct</short_name>
   <type>route</type>
  </address_component>
  <address_component>
   <long_name>Sand Ridge</long_name>
   <short_name>Sand Ridge</short_name>
   <type>neighborhood</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>Birmingham</long_name>
   <short_name>Birmingham</short_name>
   <type>locality</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>Jefferson</long_name>
   <short_name>Jefferson</short_name>
   <type>administrative_area_level_2</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name></long_name>
   <short_name></short_name>
   <type>administrative_area_level_1</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>United States</long_name>
   <short_name>US</short_name>
   <type>country</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>35209</long_name>
   <short_name>35209</short_name>
   <type>postal_code</type>
  </address_component>
  <geometry>
   <location>
    <lat>33.4415480</lat>
    <lng>-86.8434000</lng>
   </location>
   <location_type>ROOFTOP</location_type>
   <viewport>
    <southwest>
     <lat></lat>
     <lng></lng>
    </southwest>
    <northeast>
     <lat></lat>
     <lng></lng>
    </northeast>
   </viewport>
  </geometry>
 </result>
</GeocodeResponse>

Specifically, I am grabbing the looking at the <geometry> parent and extracting children the <lat> and <lng> attributes to map my address.

 

However, recently Google has started returning a much longer result, but only certain address (I have yet to figure out why):

<?xml version="1.0" encoding="UTF-8"?>
<GeocodeResponse>
 <status>OK</status>
 <result>
  <type>route</type>
  <formatted_address>Monroe Street, Ashland, KY 41102, USA</formatted_address>
  <address_component>
   <long_name>Monroe Street</long_name>
   <short_name>Monroe St</short_name>
   <type>route</type>
  </address_component>
  <address_component>
   <long_name>Ashland</long_name>
   <short_name>Ashland</short_name>
   <type>locality</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>Boyd</long_name>
   <short_name>Boyd</short_name>
   <type>administrative_area_level_2</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>Kentucky</long_name>
   <short_name>KY</short_name>
   <type>administrative_area_level_1</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>United States</long_name>
   <short_name>US</short_name>
   <type>country</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>41102</long_name>
   <short_name>41102</short_name>
   <type>postal_code</type>
  </address_component>
  <geometry>
   <location>
    <lat>38.4541724</lat>
    <lng>-82.6490458</lng>
   </location>
   <location_type>GEOMETRIC_CENTER</location_type>
   <viewport>
    <southwest>
     <lat>38.4529672</lat>
     <lng>-82.6524377</lng>
    </southwest>
    <northeast>
     <lat>38.4559500</lat>
     <lng>-82.6456744</lng>
    </northeast>
   </viewport>
   <bounds>
    <southwest>
     <lat>38.4529672</lat>
     <lng>-82.6524377</lng>
    </southwest>
    <northeast>
     <lat>38.4559500</lat>
     <lng>-82.6456744</lng>
    </northeast>
   </bounds>
  </geometry>
  <partial_match>true</partial_match>
 </result>
 <result>
  <type>route</type>
  <formatted_address>Monroe Street, Ashland, OH 44805, USA</formatted_address>
  <address_component>
   <long_name>Monroe Street</long_name>
   <short_name>Monroe St</short_name>
   <type>route</type>
  </address_component>
  <address_component>
   <long_name>Ashland</long_name>
   <short_name>Ashland</short_name>
   <type>locality</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>Ashland</long_name>
   <short_name>Ashland</short_name>
   <type>administrative_area_level_2</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>Ohio</long_name>
   <short_name>OH</short_name>
   <type>administrative_area_level_1</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>United States</long_name>
   <short_name>US</short_name>
   <type>country</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>44805</long_name>
   <short_name>44805</short_name>
   <type>postal_code</type>
  </address_component>
  <geometry>
   <location>
    <lat>40.8766037</lat>
    <lng>-82.3267712</lng>
   </location>
   <location_type>GEOMETRIC_CENTER</location_type>
   <viewport>
    <southwest>
     <lat>40.8750356</lat>
     <lng>-82.3281820</lng>
    </southwest>
    <northeast>
     <lat>40.8780371</lat>
     <lng>-82.3254840</lng>
    </northeast>
   </viewport>
   <bounds>
    <southwest>
     <lat>40.8750356</lat>
     <lng>-82.3280602</lng>
    </southwest>
    <northeast>
     <lat>40.8780371</lat>
     <lng>-82.3256058</lng>
    </northeast>
   </bounds>
  </geometry>
  <partial_match>true</partial_match>
 </result>
 <result>
  <type>route</type>
  <formatted_address>Monroe Street, Ashland, OR 97520, USA</formatted_address>
  <address_component>
   <long_name>Monroe Street</long_name>
   <short_name>Monroe St</short_name>
   <type>route</type>
  </address_component>
  <address_component>
   <long_name>Ashland</long_name>
   <short_name>Ashland</short_name>
   <type>locality</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>Jackson</long_name>
   <short_name>Jackson</short_name>
   <type>administrative_area_level_2</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>Oregon</long_name>
   <short_name>OR</short_name>
   <type>administrative_area_level_1</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>United States</long_name>
   <short_name>US</short_name>
   <type>country</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>97520</long_name>
   <short_name>97520</short_name>
   <type>postal_code</type>
  </address_component>
  <geometry>
   <location>
    <lat>42.1838843</lat>
    <lng>-122.6940978</lng>
   </location>
   <location_type>GEOMETRIC_CENTER</location_type>
   <viewport>
    <southwest>
     <lat>42.1819041</lat>
     <lng>-122.6954490</lng>
    </southwest>
    <northeast>
     <lat>42.1846021</lat>
     <lng>-122.6927510</lng>
    </northeast>
   </viewport>
   <bounds>
    <southwest>
     <lat>42.1826219</lat>
     <lng>-122.6944420</lng>
    </southwest>
    <northeast>
     <lat>42.1838843</lat>
     <lng>-122.6937580</lng>
    </northeast>
   </bounds>
  </geometry>
  <partial_match>true</partial_match>
 </result>
</GeocodeResponse>

Notice how there are now multiple instances of <lag> and <lng>.  I now need to be able to target a specific parent so that I can extract the correct child attributes for <lat> <lng>.

 

The CF specified in my post above only allows me to specify one named data attribute and this happens to default to the first instance of that attribute.  In my case, this causes the address to be mapped WAY outside of where it actually is.  I am also using the "Insert from URL" script step to grab the result of the API query.

recently Google has started returning a much longer result, but only certain address (I have yet to figure out why):

 

AFAICT, the difference between the two responses is the number of results returned: the first response contains one result only, while the second response returns three results with three different addresses:

 

Monroe Street, Ashland, KY 41102, USA

Monroe Street, Ashland, OH 44805, USA

Monroe Street, Ashland, OR 97520, USA

 

I am guessing this would be caused by the submitted search criteria finding three matching addresses in three different states - not necessarily by any change on Google's part.

 

 

 

EDIT:

I also notice that the result in the first response has "street_address" as the <type>. The three results in the second response are of type "route". Not sure what significance, if any, this has.

 

 

 

I now need to be able to target a specific parent so that I can extract the correct child attributes for <lat> <lng>.

 

Well, which one? Properly, you'd import the entire response into a child table, creating a separate related record for each result.

 

 

BTW, do I understand correctly that the request is submitted to a https (i.e. secure) URL?

Edited by comment

Create an account or sign in to comment

Important Information

By using this site, you agree to our Terms of Use.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.