Copy link to clipboard
Copied
I'm using XmlParse to pull data out of xml files. How do you handle cases where some of the xml contain elements/attributes that others do not? There must be a graceful way to test for the existance of an element etc without using a try/catch, but I'm not sure what it is. Any suggestions?
Copy link to clipboard
Copied
Have you tried XMLSearch() ?
http://livedocs.adobe.com/coldfusion/8/functions_t-z_24.html
Copy link to clipboard
Copied
This is an example of what I'm doing:
<cffile action="read" file="#currentXMLPath#" variable="xmlString" charset="utf-8" >
<cfset mdXML = XmlParse(xmlString)>
<cfset screens = XmlSearch(mdXML, "//*[local-name()='screens']" )>
<cfset screenArray = #screens[1].screen#>
<cfloop from="1" to="#ArrayLen(screenArray)#" index="i" step="1">
<cfset objectInfo = #screenArray.objectInfo.XmlText#>
....
</cfloop>
The issue I'm having is that sometimes the objectInfo element (and others) won't be present in the xml, so I need to test for it's existance before trying to read it's value. Am I going about this the wrong way?
Copy link to clipboard
Copied
OK, so why don't you alter the xPath in your xmlSearch() to retrieve only the nodes you want, rather than get a whole bunch of nodes and then work out whether they're the ones you want or not?
As BKBK suggested, seeing some sample XML indicating which nodes you want would help.
--
Adam
Copy link to clipboard
Copied
Basically, I want everything out of the xml, but each particular xml file may have different elements. I can attach an example of the xml, but it would be missing elements and attributes that another one might have. Is this an unusual situation?
Copy link to clipboard
Copied
Well you can't want ALL the nodes, otherwise you'd not be doing an xmlSearch() to return a subset of nodes...
--
Adam
Copy link to clipboard
Copied
I thought that XmlSearch was used to isolate the root node from the xml.
For example, my xml always has the following root node:
<?xml version="1.0" encoding="utf-8"?>
<screens>
<screen>
....
</screen>
<screen>
....
</screen>
</screens>
So, in this case, I'm using <cfset screens = XmlSearch(mdXML, "//*[local-name()='screens']" )> to isolate the screens root node, and I can then loop through an array of screen nodes using <cfset screenArray = #screens[1].screen#>.
I'm new to coldfusion xml, so perhaps there is another (better) way of doing this.
Copy link to clipboard
Copied
OK, well first things first, read this:
xmlSearch():
http://livedocs.adobe.com/coldfusion/8/htmldocs/functions_t-z_24.html
xPath:
http://en.wikipedia.org/wiki/XPath
http://www.w3.org/TR/xpath/
Easy to understand xPath tutorial:
http://www.zvon.org/xxl/XPathTutorial/General/examples.html
Having read all that, redfine your requirement - because I think your current one is based on inaccurate suppositions - and post back. Don't second-guess how to fulfil your requirement, just tell us what the requirement is.
--
Adam
Copy link to clipboard
Copied
Broodmdh001 wrote:
I thought that XmlSearch was used to isolate the root node from the xml.
For example, my xml always has the following root node:
<?xml version="1.0" encoding="utf-8"?>
<screens>
<screen>....
</screen>
<screen>
....
</screen>
</screens>
So, in this case, I'm using <cfset screens = XmlSearch(mdXML, "//*[local-name()='screens']" )> to isolate the screens root node, and I can then loop through an array of screen nodes using <cfset screenArray = #screens[1].screen#>.
I'm new to coldfusion xml, so perhaps there is another (better) way of doing this.
You are really on the right track. New to Coldfusion or not, it doesn't get better than what you're doing. To generalize, use xmlChildren for the array. Here's an example:
<cfxml variable="mdXML">
<screens>
<screen myAttrib="bkbk1">screen1</screen>
<screen myAttrib="bkbk2">screen2</screen>
<screen myAttrib="bkbk3">screen3</screen>
</screens>
</cfxml>
<cfset screens = XmlSearch(mdXML, "//*[local-name()='screens']" )>
<cfset screenArray = screens[1].xmlChildren>
<cfset secondAttrib = screenArray[2].xmlAttributes.myAttrib>
<!--- alternative --->
<!--- <cfset secondAttrib = screens[1].xmlChildren[2].xmlAttributes.myAttrib> --->
<cfset thirdElementText = screenArray[3].xmlText>
<!--- alternative --->
<!--- <cfset thirdElementText = screens[1].xmlChildren[3].xmlText> --->
Copy link to clipboard
Copied
It will certainly help to give an XML example, showing the data yo wish to pull out. by the way, xmlParse is for creating the XML document object, not for fetching data from the XML.