Skip to main content
added 12 characters in body
Source Link
  1. The first function strips off the document header and the declaration.

  2. The second one pulls off the "Fleet" and maps across the list of vehicles in the fleet, because there are potentially many vehicles.

  3. The third function pulls out the name of the specific vehicle you are looking for (say "BJ#00") with the IF statement and then continues the recursion stripping off the "SomeVehicle" XMLElement.

  4. The final step takes the list of attributes and stuffs the list into a global list for further processing (maybe not the most elegant part) but I think this is the general solution to the problem you are posing, which at a high level is "how can I extract the traits of a specific vehcile?" This leaves all the traits together in a form can be post-processed as you need.

  5. This looks like {XMLElement["Shape", {}, {"parallelepiped"}], XMLElement["Length", {"unit" -> "Distance"}, {"0.5"}], XMLElement["Width", {"unit" -> "Distance"}, {"0.4"}], XMLElement["Height", {"unit" -> "Distance"}, {"0.3"}], XMLElement["Density", {"unit" -> "Density"}, {"500.0"}]}

  6. From here you can extract the attributes by manipulating the list directly, or if you prefer you can use Cases like this:

    selectedAttr = Cases[busAttGL, XMLElement["Width", ___, ___]][[1]]

selectedAttr=Cases[busAttGL, XMLElement["Width", ___, ___]][[1]]

{"unit" /. First[Cases[selectedAttr, {"unit" -> "Distance"}]],selectedAttr[[3]][[1]]}

{"unit" /. First[Cases[selectedAttr, {"unit" -> "Distance"}]],selectedAttr[[3]][[1]]}

`{selectedAttr[[2]][[1]][[2]], selectedAttr[[3]][[1]]}`
  1. The first function strips off the document header and the declaration.

  2. The second one pulls off the "Fleet" and maps across the list of vehicles in the fleet, because there are potentially many vehicles.

  3. The third function pulls out the name of the specific vehicle you are looking for (say "BJ#00") with the IF statement and then continues the recursion stripping off the "SomeVehicle" XMLElement.

  4. The final step takes the list of attributes and stuffs the list into a global list for further processing (maybe not the most elegant part) but I think this is the general solution to the problem you are posing, which at a high level is "how can I extract the traits of a specific vehcile?" This leaves all the traits together in a form can be post-processed as you need.

  5. This looks like {XMLElement["Shape", {}, {"parallelepiped"}], XMLElement["Length", {"unit" -> "Distance"}, {"0.5"}], XMLElement["Width", {"unit" -> "Distance"}, {"0.4"}], XMLElement["Height", {"unit" -> "Distance"}, {"0.3"}], XMLElement["Density", {"unit" -> "Density"}, {"500.0"}]}

  6. From here you can extract the attributes by manipulating the list directly, or if you prefer you can use Cases like this:

    selectedAttr = Cases[busAttGL, XMLElement["Width", ___, ___]][[1]]

{"unit" /. First[Cases[selectedAttr, {"unit" -> "Distance"}]],selectedAttr[[3]][[1]]}
{selectedAttr[[2]][[1]][[2]], selectedAttr[[3]][[1]]}
  1. The first function strips off the document header and the declaration.

  2. The second one pulls off the "Fleet" and maps across the list of vehicles in the fleet, because there are potentially many vehicles.

  3. The third function pulls out the name of the specific vehicle you are looking for (say "BJ#00") with the IF statement and then continues the recursion stripping off the "SomeVehicle" XMLElement.

  4. The final step takes the list of attributes and stuffs the list into a global list for further processing (maybe not the most elegant part) but I think this is the general solution to the problem you are posing, which at a high level is "how can I extract the traits of a specific vehcile?" This leaves all the traits together in a form can be post-processed as you need.

  5. This looks like {XMLElement["Shape", {}, {"parallelepiped"}], XMLElement["Length", {"unit" -> "Distance"}, {"0.5"}], XMLElement["Width", {"unit" -> "Distance"}, {"0.4"}], XMLElement["Height", {"unit" -> "Distance"}, {"0.3"}], XMLElement["Density", {"unit" -> "Density"}, {"500.0"}]}

  6. From here you can extract the attributes by manipulating the list directly, or if you prefer you can use Cases like this:

selectedAttr=Cases[busAttGL, XMLElement["Width", ___, ___]][[1]]

{"unit" /. First[Cases[selectedAttr, {"unit" -> "Distance"}]],selectedAttr[[3]][[1]]}

`{selectedAttr[[2]][[1]][[2]], selectedAttr[[3]][[1]]}`
Source Link

I think that using Cases to break apart XML is probably not the right way to go. When working with the nested structure like this, the natural approach is to use recursion. The following code could use polishing but it suggests a general way to deal with XML. The basic idea is that you find the head of the structure and strip it off, then recurse on what's left. Given the myriad of forms that XML can take, this allows you to customize the code to whatever kind of nesting XML throws at you, and the parsing is pretty mechanical once you understand the XML nesting (which unfortunately you must do if you want to work with XML!)

trf[XMLObject["Document"][decl_, rest_, {}], bS_] := trf[rest, bS];
trf[XMLElement["Fleet", {}, fleetL_], bS_] := trf[#, bS] & /@ fleetL;
trf[XMLElement["SomeVehicle", {}, vehL_], bS_] := 
  If[vehL[[1]] == XMLElement["Name", {}, {bS}],
   trf[Rest[vehL]]];
trf[{XMLElement["Bus", {}, busAttL_]}] := busAttGL = busAttL;


 (* called with *)
 trf[fleetXMLString, "BJ#00"];
  1. The first function strips off the document header and the declaration.

  2. The second one pulls off the "Fleet" and maps across the list of vehicles in the fleet, because there are potentially many vehicles.

  3. The third function pulls out the name of the specific vehicle you are looking for (say "BJ#00") with the IF statement and then continues the recursion stripping off the "SomeVehicle" XMLElement.

  4. The final step takes the list of attributes and stuffs the list into a global list for further processing (maybe not the most elegant part) but I think this is the general solution to the problem you are posing, which at a high level is "how can I extract the traits of a specific vehcile?" This leaves all the traits together in a form can be post-processed as you need.

  5. This looks like {XMLElement["Shape", {}, {"parallelepiped"}], XMLElement["Length", {"unit" -> "Distance"}, {"0.5"}], XMLElement["Width", {"unit" -> "Distance"}, {"0.4"}], XMLElement["Height", {"unit" -> "Distance"}, {"0.3"}], XMLElement["Density", {"unit" -> "Density"}, {"500.0"}]}

  6. From here you can extract the attributes by manipulating the list directly, or if you prefer you can use Cases like this:

    selectedAttr = Cases[busAttGL, XMLElement["Width", ___, ___]][[1]]

And then you can take the rule and the value and put them together using Cases again and the rule:

{"unit" /. First[Cases[selectedAttr, {"unit" -> "Distance"}]],selectedAttr[[3]][[1]]}

I would probably just go into the list itself:

{selectedAttr[[2]][[1]][[2]], selectedAttr[[3]][[1]]}

Both produce {"Distance", "0.4"} which is what you are after. This makes it fairly straightforward to do any permutation of bus attributes etc.

Both of these are kind of unpretty and I'm sure somebody on the forum will suggest a cleaner way to go from the XMLElement form to what you want.