xmlGetWhere ( )

Function stats

Average user rating
5.0000
37
155
9999
Support
FileMaker 8.0 +
Date posted
20 December 2008
Last updated
05 June 2012
Version
Recursive function
Yes

Author Info
 Fabrice

79 functions

Average Rating 4.4

author_avatar



 

Function overview

Prototype

xmlGetWhere  ( _xml;   _tag;   _tagWhere;   _value )


Parameters

_xml  an xml string


_tag  the tag (node) to extract


_tagWhere  the nested tag (node) where the value is required


_value  


Description

Tags:  xml   Text Parsing   Debug  

In an xml structure, extracts the nodes ( _tag ) where a nested tag matches a value.

Examples

Sample input

if _xml is:
<contact><ID>67</ID><Name>Wesson</Name></contact>
<contact><ID>124</ID><Name>Smith</Name></contact>
<contact><ID>780</ID><Name>Wesson</Name></contact>

Example :
// The contact tag(s) that where a Name tag equals Wesson
xmlGetWhere ( _xml ; "contact" ; "Name" ; "Wesson" )


Sample output

<contact><ID>67</ID><Name>Wesson</Name></contact>
<contact><ID>780</ID><Name>Wesson</Name></contact>

 

Function code

/*
xmlGetWhere ( _xml ; _tag ; _tagWhere ; _value )

by Fabrice Nordmann

1-more-thing

http://www.1-more-thing.com

v.3 Dec 2010
- completely rewritten
- much faster
- not case sensitive
- solved an issue where nested nodes had their parent node name in their name (like <CONTACT><CONTACT NAME></CONTACT NAME></CONTACT>)
- returns a node if any of the 'tagwhere' equals _value (was taking only the first one into account)
v.2.2 Jul 2009
- removed empty values
v.2.1 Jan 2009
- even faster. Ready for Sokoban 3D ;-)
v.2.0 Jan 2009
- re-written using CustomList (not recursive), so it shouldn't smoke intel CPUs anymore :)
v.1.0 Dec 2008


In an xml structure, extracts the nodes ( _tag ) where a nested tag matches a value.


Requires :
CustomList () : http://www.fmfunctions.com/fname/customlist


Parameters:
_xml : an xml string
_tag : the tag (node) to extract
_tagWhere : the nested tag (node) where the value is required
_value : what needs to be found in _tagWhere for _tag to be extracted


Example:
if _xml is:
<address book>
<contact><ID>67</ID><Name>Wesson</Name></contact>
<contact><ID>124</ID><Name>Smith</Name></contact>
<contact><ID>780</ID><Name>Wesson</Name></contact>
</address book>

------------------------

// The contact tag(s) that where a Name tag equals Wesson

xmlGetWhere ( _xml ; "contact" ; "Name" ; "Wesson" ) =
"<contact><ID>67</ID><Name>Wesson</Name></contact>
<contact><ID>780</ID><Name>Wesson</Name></contact>"

------------------------
*/
Case ( isEmpty ( _xml ) ; "" ;
Case ( IsEmpty ( $cf_i ) ;
    Let ([
        $cf_i = 0 ;
        $cf_xml = Substitute ( _xml ; ¶ ; "#CR#" ) ;
        $cf_xmlw_value = Substitute ( _value ; ¶ ; "#CR#" ) ;
        $cf_tag = "<" & _tag & ">" ;
        $cf_length = Length ( $cf_tag ) ;
        $cf_tagClosing = "</" & _tag & ">" ;
        $cf_tagCount = PatternCount ( $cf_xml ; $cf_tag ) ;
        $cf_tagWhere = _tagwhere ;
        $cf_tagWhereWdata = "<" & $cf_tagWhere & ">" & $cf_xmlw_value & "</" & $cf_tagWhere & ">"
    ];
        xmlGetWhere ( $cf_xml ; "" ; "" ; "" )
    ) ;
    Let ( $cf_i = $cf_i + 1 ; "" ) &
    Case (
        $cf_i <= $cf_tagCount ;
            // modify the xml so the opening tag is marked
            xmlGetWhere ( Replace ( _xml ; Position ( _xml ; $cf_tag ; 1 ; $cf_i ) ; 0 ; "#T#A#G#" ) ; "" ; "" ; "" ) ;
        $cf_i <= $cf_tagCount * 2 ;
            //do the same with closing tags
            xmlGetWhere ( Replace ( _xml ; Position ( _xml ; $cf_tagClosing ; 1 ; $cf_i / 2 ) + Length ( $cf_tagClosing ) ; 0 ; "#T#A#G#" ) ; "" ; "" ; "" ) ;

            // extract the matching values
            Let ([
                $cf_xml = Substitute ( _xml ; "#T#A#G#" ; ¶ ) ;
                _result = //_xml
                    Substitute (
                        CustomList ( 1 ; ValueCount ( $cf_xml ) ; "let ( x = getvalue ( $cf_xml ; [n] ) ; case ( left ( x ; $cf_length ) = $cf_tag and PatternCount ( x ; $cf_tagWhereWdata ) ; x ))" ) ;

                        "#CR#" ; ¶
                    ) ;

                // clean the mess
                $cf_i = "" ;
                $cf_xml = "" ;
                $cf_xmlw_value = "" ;
                $cf_tag = "" ;
                $cf_length = "" ;

                $cf_tagClosing = "" ;
                $cf_tagCount = "" ;
                $cf_tagWhere = "" ;
                $cf_tagWhereWdata = ""        
                ];
                _result
            )

    )
)
)

// ===================================
/*

    This function is published on FileMaker Custom Functions
    to check for updates and provide feedback and bug reports
    please visit http://www.fmfunctions.com/fid/155

    Prototype: xmlGetWhere( _xml; _tag; _tagWhere; _value )
    Function Author: Fabrice (http://www.fmfunctions.com/mid/37)
    Last updated: 05 June 2012
    Version: 3.2

*/
// ===================================

 

Comments

Fabrice
20 December 2008



I would be glad to have comments on this one, especially about the documentation, parameter names or the function name (I'm not very happy with those).
  General comment
Michael W.
14 February 2009



This function is invaluable in a project that I am doing. With this one and the GetXMLNode function that I wrote it took care of handling the XML that I needed to parse very nicely. Thanks for the great work!
  General comment
Darren Lunn
18 August 2010



This works perfectly for me. Thanks for this Fabrice. I don't know if this answers your request (above) but I called it: xml.return.query

Thanks again.
  General comment
Andries Heylen
05 June 2012



hi Fabrice
just a "stupid" remark: it doesn't work when the xml parameter is empty, you receive the error of CustomList, would be nice if it returns just empty.

thx:-)

  General comment