Reputation: 37
I've used this excellent forum to teach myself some basic xpath to query an .XML file. I've got a sample of my XML file here, and I'm trying to import the [X,Y] coordinates of 3 objects in the XML file using Matlab:
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ROI array</key>
<array>
<dict>
<key>Comments</key>
<string></string>
<key>Name</key>
<string>Unnamed</string>
<key>ROIPoints</key>
<array>
<string>{129.24051549947484, 263.66036033996352}</string>
<string>{114.61421850240453, 278.56760216125258}</string>
<string>{123.11826208150609, 289.73859978088149}</string>
<string>{125.11111111111111, 295.77777777777777}</string>
</array>
<key>Slice</key>
<integer>58</integer>
</dict>
<dict>
<key>Comments</key>
<string></string>
<key>Name</key>
<string>Unnamed</string>
<key>ROIPoints</key>
<array>
<string>{127.09352448499425, 261.31629753478774}</string>
<string>{112.50917389905675, 277.25509453185805}</string>
<string>{126.061969309213, 291.36980247863539}</string>
<string>{141.48499634778722, 292.16234398254164}</string>
<string>{149.71229126966222, 277.81281090148696}</string>
</array>
<key>Slice</key>
<integer>59</integer>
</dict>
<dict>
<key>Comments</key>
<string></string>
<key>Name</key>
<string>Unnamed</string>
<key>ROIPoints</key>
<array>
<string>{134.32833430087788, 258.21743274101027}</string>
<string>{117.0812182120107, 266.44891620048293}</string>
<string>{114.41427180087788, 292.20427203544386}</string>
<string>{128.80573603427632, 299.11905932792433}</string>
<string>{147.92307612216695, 299.11905932792433}</string>
<string>{152.73700281894429, 285.80526996024855}</string>
<string>{154.32626673495992, 268.51202655204543}</string>
</array>
<key>Slice</key>
<integer>60</integer>
</dict>
</array>
</dict>
</plist>
I've managed to export all of the coordinates using this Matlab code:
expression_2 = xpath.compile('plist/dict/array/dict/array/string');
nodeList_2 = expression_2.evaluate(docNode, XPathConstants.NODESET);
for i = 1:nodeList_2.getLength
node = nodeList_2.item(i-1);
coordinate_node{i} = char(node.getFirstChild.getNodeValue);
end
Does anyone know of an xpath query whereby I could count the NUMBER of [X,Y] coordinates in each object? I.e. something that returns 4 coordinates for the first object, 5 coordinates in the second and 7 coordinates in the 3rd?
Thanks, Jim
Upvotes: 2
Views: 2097
Reputation: 32930
You're on the right track. However, the problem is that your code extracts all "string" nodes in a flat way, disregarding parent "array" nodes. This way you cannot tell which coordinate belongs to which object.
If you modify your code a little bit so that it would traverse through the "array" and "string" nodes in a hierarchical way, it can work like you want to:
%// Extract 'array' nodes
expr_array = xpath.compile('plist/dict/array/dict/array');
nodeList_array = expr_array.evaluate(docNode, XPathConstants.NODESET);
C = cell(nodeList_array.getLength, 1);
for k = 1:nodeList_array.getLength
%// Extract 'string' nodes
node_array = nodeList_array.item(k - 1);
expr_string = xpath.compile('string');
nodeList_string = expr_string.evaluate(node_array, XPathConstants.NODESET);
coordinates = zeros(nodeList_string.getLength, 2);
for m = 1:nodeList_string.getLength
node_string = nodeList_string.item(m - 1);
s = char(node_string.getFirstChild.getNodeValue); %// Extract string
coordinates(m, :) = str2num(s(2:end - 1)); %// Convert to numbers
end
C{k} = coordinates;
end
Now cell array C
contains all coordinates (by the way, I converted them to numerical values so that they can be stored in a matrix and manipulated easily):
C{1} =
129.2405 263.6604
114.6142 278.5676
123.1183 289.7386
125.1111 295.7778
C{2} =
127.0935 261.3163
112.5092 277.2551
126.0620 291.3698
141.4850 292.1623
149.7123 277.8128
C{3} =
134.3283 258.2174
117.0812 266.4489
114.4143 292.2043
128.8057 299.1191
147.9231 299.1191
152.7370 285.8053
154.3263 268.5120
Now, if you want the number of coordinates in each cell (object), simply do this:
cellfun(@(c)size(c, 1), C)
and you'll get the desired result:
ans=
4
5
7
Upvotes: 1
Reputation: 3448
I am not familiar with your matlab's XPath implementation, but XPath do have aggregation functions and I have used them with Java:
http://www.w3.org/TR/xpath-functions/#func-count
please refer your matlab's manual on this topic first. You can also have a glance how to use it in this similar question.
How do I use XPath to count the number of nodes with a certain attribute
Upvotes: 1