Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'm trying to come to grips with parsing an XML file but I'm having difficulty working out how to extract specific attribute data from an XMLElement. Sample XML file below:

<!DOCTYPE DEXXMLDoc SYSTEM "DEXXMLDoc.DTD">
<DEXXMLDoc name="RSM-a.xml" creator="DX8" version="8.0.6">
<designInfo studyType="ResponseSurface" designType="CCD" noOfRuns="20" noOfFactors="3" noOfResponses="2">
<designNotes>This data file created by Design-Expert 6</designNotes>
</designInfo>
<blockInfo>
<block code="0" name="Block 1"/>
<block code="1" name="Block 2"/>
</blockInfo>
<factorInfo>
<factor id="A" name="time" unit="min." type="Numeric">
<numeric low="40" high="50" stdDev="0"/>
</factor>
<factor id="B" name="temperature" unit="deg C" type="Numeric">
<numeric low="80" high="90" stdDev="0"/>
</factor>
<factor id="C" name="catalyst" unit="%" type="Numeric">
<numeric low="2" high="3" stdDev="0"/>
</factor>
</factorInfo>

As you can see, this particular XML file relies on attributes to hold much of the data. I have no trouble selecting entire XMLElement(s) by name using Cases but I can't seem to work out how to extract specific attribute data by name. For example, I'd like to be able to extract the studyType attribute from the designInfo element.

This is what the XMLElement that I'm working with looks like:

    XMLObject[
  "Document"][{XMLObject["Doctype"]["DEXXMLDoc", 
   "System" -> "DEXXMLDoc.DTD"]}, 
 XMLElement[
  "DEXXMLDoc", {"name" -> "RSM-a.xml", "creator" -> "DX8", 
   "version" -> "8.0.6"}, {XMLElement[
    "designInfo", {"studyType" -> "ResponseSurface", 
     "designType" -> "CCD", "noOfRuns" -> "20", "noOfFactors" -> "3", 
     "noOfResponses" -> "2"}, {XMLElement[
      "designNotes", {}, {"This data file created by Design-Expert \
6"}]}], XMLElement[
    "blockInfo", {}, {XMLElement[
      "block", {"code" -> "0", "name" -> "Block 1"}, {}], 
     XMLElement["block", {"code" -> "1", "name" -> "Block 2"}, {}]}],

Does anyone have experience in extracting named attribute data from XMLElements?

share|improve this question
    
Did you get the XMLObject by using something like ImportString[Import[xmlFileName], "XML"]? Including that may help our users. –  Jacob Akkerboom Jul 23 '13 at 10:29
    
I just used the plain Import function like so: DX8 = Import["RSM-a.xml", "XML", "ReadDTD" -> False] –  CrustyNoodle Jul 29 '13 at 5:13

1 Answer 1

up vote 5 down vote accepted

I can't try it out because your snippet lacks some brackets, but perhaps this will do the trick:

Cases[snippet,
 XMLElement["designInfo",
   {"studyType" -> atrib_, ___}, ___] :> atrib, \[Infinity]]
share|improve this answer
    
Thanks, that works perfectly! Easy when you know how eh! Sorry for not posting the entire list - just trying to save space. –  CrustyNoodle Mar 26 '13 at 12:22
4  
That presumes that "studyType" will always be first, and while it is likely to follow the order in the XML, there is no guarantee it will be first. I recommend using {___,"studyType" -> atrib_, ___}, instead. Or, reducing it to simply HoldPattern["studyType" -> atrib_] :> atrib, instead of XMLElement[...], as Cases will search the entire document with the level spec set to Infinity. –  rcollyer Mar 26 '13 at 12:48
    
You are correct. The order is not guaranteed to be consistent. I'll try the HoldPattern[...] suggestion as recommended. Thanks for your help. –  CrustyNoodle Mar 26 '13 at 22:18

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.