Friday, September 11, 2015

Filemaker example of Xpath

Previously I talked about using Filemaker to extracting xml node text without using plugins. I have created a working script that does just that. You just need to call the first script that does a "Tidy". The script will remove unnecessary carriage return, tabs and extra spaces between nodes. It also add carriage return after every node. You can get the node text value by adding the xpath path with a carriage return in front of the xml as one parameter to the second script.

The reason for putting them in two script is that you only need to "Tidy" the xml once but you need execute  the second script a number of times to extract multiple node values.

The first script is called "xtidy". The script is as follows

Set Variable [ $xml ; Value: Get(ScriptParameter) ] 
Set Variable [ $xlen ; Value: Length ( $xml ) ] 
Set Variable [ $ccount ; Value: 1 ] 
Set Variable [ $xout ; Value: "" ] 
Set Variable [ $xfound ; Value: 0 ] 
Set Variable [ $xtext ; Value: "" ] 
Loop
 Exit Loop If [ $ccount > $xlen ] 
 Set Variable [ $xsearch ; Value: Middle ( $xml ; $ccount ; 1) ] 
 If [ $xsearch = ">" ] 
  Set Variable [ $xfound ; Value: 1 ] 
  Set Variable [ $xout ; Value: $xout & $xsearch ] 
 Else If [ $xsearch = "<" ] 
  Set Variable [ $xtext ; Value: Substitute ( $xtext ; Char ( 13 ) ; "" ) ] 
  Set Variable [ $xtext ; Value: Substitute ( $xtext ; Char ( 11 ) ; "" ) ] 
  Set Variable [ $xtext ; Value: Trim ( $xtext ) ] 
  Set Variable [ $xout ; Value: $xout & $xtext & "<" ] 
  Set Variable [ $xtext ; Value: "" ] 
  Set Variable [ $xfound ; Value: 0 ] 
 Else If [ $xfound = 1 ] 
  Set Variable [ $xtext ; Value: $xtext & $xsearch ] 
 Else
  Set Variable [ $xout ; Value: $xout & $xsearch ] 
 End If
 Set Variable [ $ccount ; Value: $ccount+1 ] 
End Loop
Set Variable [ $xout ; Value: Substitute ( $xout ; "><" ; ">" & ¦ & "<" ) ] 
Exit Script [ Result: $xout ] 
The second script is call "Xpath". The script is as follows



# Just add the path with a carriage return to the xml like $xpath & $xml as parameter
Set Variable [ $xml ; Value: Get(ScriptParameter) ] 
Set Variable [ $xmlcount ; Value: PatternCount ( $xml ; ¦ ) ] 
Set Variable [ $xpath ; Value: GetValue($xml;1) ] 
Set Variable [ $xpath ; Value: Substitute ( $xpath ; "//" ; "" ) ] 
Set Variable [ $xcount ; Value: PatternCount ( $xpath ; "/" )+1 ] 
Set Variable [ $xpath ; Value: Substitute ( $xpath ; "/" ; ¦ ) ] 
Set Variable [ $pathLevelCount ; Value: 0 ] 
Set Variable [ $pathRepeatCount ; Value: 0 ] 
Set Variable [ $lastXsearch ; Value: "" ] 
Set Variable [ $lastXsearchCount ; Value: 0 ] 
Set Variable [ $xmlresult ; Value: "" ] 
Set Variable [ $xcurPath ; Value: "/" ] 
Set Variable [ $xlevel ; Value: 0 ] 
Set Variable [ $xlevelCurrent ; Value: 0 ] 
Set Variable [ $ccount ; Value: 1 ] 
Set Variable [ $xml ; Value: Middle ( $xml ; Position ( Upper ($xml) ; "" ; 1 ; 1 )+15 ; Position ( Upper($xml) ; "" ; 1 ; 1 )-Position ( Upper($xml) ; "" ; 1 ; 1 )-15 ) ] 
Set Variable [ $xmlcount ; Value: PatternCount ( $xml ; ¦ ) ] 
# Script to find lowest level of the first search path
Loop
 Exit Loop If [ $ccount > $xmlcount ] 
 Set Variable [ $xsearch ; Value: GetValue($xml;$ccount) ] 
 If [ Left ( $xsearch ; 2 ) = "</" ] 
  Set Variable [ $xlevelCurrent ; Value: $xlevelCurrent-1 ] 
 Else If [ PatternCount ( $xsearch ; "<" ) = 1 ] 
  Set Variable [ $xlevelCurrent ; Value: $xlevelCurrent+1 ] 
 End If
 Set Variable [ $xnode ; Value: Middle ( $xsearch ; 2 ; Position ( $xsearch ; ">" ; 1 ; 1 )-2) ] 
 If [ PatternCount ($xnode;"/")  ­ 0 ] 
  Set Variable [ $xnode ; Value: ¦ & ¦ & ¦ & ¦ ] 
 End If
 If [ Position ( GetValue($xpath;1) ; $xnode ; 1 ; 1 )  > 0 ] 
  If [ $xlevel = 0 ] 
   Set Variable [ $xlevel ; Value: $xlevelCurrent ] 
  Else If [ $xlevel > $xlevelCurrent ] 
   Set Variable [ $xlevel ; Value: $xlevelCurrent ] 
  End If
 End If
 Set Variable [ $ccount ; Value: $ccount + 1 ] 
End Loop
Set Variable [ $xlevelCurrent ; Value: 0 ] 
Set Variable [ $ccount ; Value: 1 ] 
Loop
 Exit Loop If [ $ccount > $xmlcount ] 
 Set Variable [ $xsearch ; Value: GetValue($xml;$ccount) ] 
 If [ Left ( $xsearch ; 2 ) = "</" ] 
  Set Variable [ $xlevelCurrent ; Value: $xlevelCurrent-1 ] 
 Else If [ PatternCount ( $xsearch ; "<" ) = 1 ] 
  Set Variable [ $xlevelCurrent ; Value: $xlevelCurrent+1 ] 
 End If
 # Look for path start
 Set Variable [ $xpathtxt ; Value: GetValue($xpath;$pathLevelCount+1) ] 
 If [ Position ( $xpathtxt ; "[" ; 1 ; 1 )  ­ 0 ] 
  Set Variable [ $xpathary ; Value: Substitute ( $xpathtxt ; "[" ; ¦ ) ] 
  Set Variable [ $xtxt ; Value: GetValue($xpathary;1) ] 
  Set Variable [ $ycount ; Value: GetAsNumber ( GetValue ( $xpathary ; 2 ) ) ] 
 Else
  Set Variable [ $xtxt ; Value: $xpathtxt ] 
  Set Variable [ $ycount ; Value: 1 ] 
 End If
 # Look for path end
 Exit Loop If [ Position ( $xsearch ; $lastXsearch ; 1 ; 1 ) = 1 ] 
 If [ Position ( $xsearch ; "<" & $xtxt & ">" ; 1 ; 1 ) = 1 and $xlevelCurrent = $xlevel+$pathLevelCoiunt ] 
  Set Variable [ $pathRepeatCount ; Value: $pathRepeatCount+1 ] 
  If [ $pathRepeatCount=$ycount and $pathLevelCount  < $xcount ] 
   Set Variable [ $pathLevelCount ; Value: $pathLevelCount+1 ] 
   Set Variable [ $lastXsearch ; Value: "</" & $xsearch & ">" ] 
  End If
  If [ $pathLevelCount = $xcount and $pathRepeatCount = $ycount ] 
   Set Variable [ $xmlresult ; Value: Middle ( $xsearch ; Position ( $xsearch ; ">" ; 1 ; 1 )+1 ; Position ( $xsearch ; "<" ; 1 ; 2 )-Position ( $xsearch ; ">" ; 1 ; 1 )-1 ) ] 
   Set Variable [ $ccount ; Value: 50 ] 
  End If
  If [ $pathRepeatCount=$ycount and $pathLevelCount < $xcount ] 
   Set Variable [ $pathRepeatCount ; Value: 0 ] 
   Set Variable [ $lastXsearch ; Value: "</" & $xtxt & ">" ] 
  End If
 End If
 Set Variable [ $ccount ; Value: $ccount + 1 ] 
End Loop
Exit Script [ Result: $xmlresult ] 



No comments:

Post a Comment