dxml icon indicating copy to clipboard operation
dxml copied to clipboard

Can't get skipToPath work on real data

Open bubnenkoff opened this issue 5 years ago • 1 comments

Basic example from docs works fine:

    auto xml = "<carrot>\n" ~
               "    <foo>\n" ~
               "        <bar>\n" ~
               "            <baz/>\n" ~
               "            <other/>\n" ~
               "        </bar>\n" ~
               "    </foo>\n" ~
               "</carrot>";

	auto result = parseXML(xml);	
	auto foo = result.skipToPath("foo/bar");
	writeln("foo: ", foo.front.name);

It's print foo: bar.

But on real data http://vpaste.net/omIST

I am trying to move to next section:

	auto foo = result.skipToPath("protocolLot/applications");
	writeln("foo: ", foo.front.name);

And getting print: foo: ns2:export. Why? What's wrong? I expected it will be moved to applications section.

Here is copy-past example:

    auto xml = "<carrot>\n" ~
               "    <foo>\n" ~
               "        <bar>\n" ~
               "            <ban>\n" ~
               "	            <baz/>\n" ~
               "            </ban>\n" ~
               "            <other/>\n" ~
               "        </bar>\n" ~
               "    </foo>\n" ~
               "</carrot>";


	auto result = parseXML(xml);	
	
	auto foo = result.skipToPath("bar/ban"); // problem is here

	writeln("foo: ", foo.front.name);

bubnenkoff avatar Apr 01 '19 14:04 bubnenkoff

The path is from the start element that's currently at the front of the range. In your last example there, result starts on <carrot>. The only child element that <carrot> has is <foo>. So, any path from <carrot> must start with "foo". If you gave the path "foo/bar/ban", then your last line would print

foo: ban

Right now, what's happening is that because you gave an invalid path, skipToPath returns an empty range, and foo.empty is true. So, it's not actually valid to call foo.front at that point. It just so happens that front returns the end tag, because front doesn't assert that it wasn't called when the range was empty, and the end tag was the last data it had before the end of the range was reached. If foo.front asserted that the range was not empty, then you'd be getting an assertion failure when you attempted to call foo.front. After you call skipToPath, you should be checking whether the return value is empty so that you know whether it actually found the path that you requested. And for the path to be correct in that last example, you would either have to pop off the first element so that you were on <foo> before calling skipToPath("bar/ban"), or you would have to call skipToPath("foo/bar/ban").

For your real data, for "protocolLot/applications" to be the right path, <ns2:fcsProtocolEF3 schemeVersion="8.1"> would have to be the first element in the range, whereas I'm guessing that you were on its parent start tag <ns2:export ...>, which would mean that the path would need to be "ns2:fcsProtocolEF3/protocolLot/applications".

jmdavis avatar May 03 '19 09:05 jmdavis