Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't get skipToPath work on real data #18

Open
bubnenkoff opened this issue Apr 1, 2019 · 1 comment
Open

Can't get skipToPath work on real data #18

bubnenkoff opened this issue Apr 1, 2019 · 1 comment

Comments

@bubnenkoff
Copy link

bubnenkoff commented Apr 1, 2019

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);
@jmdavis
Copy link
Owner

jmdavis commented May 3, 2019

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".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants