Project

Profile

Help

TreeInfo.selectId() to select element by ID efficiently

Added by Marc Dzaebel almost 8 years ago

Hi,

in my Java program with Saxon 9-7, I need to find an element with ID attribute (without prefix) set to a certain value. While there are slow XPath methods like "//*[@ID='" + refID + "']", or "id(...)" there is a selectID method on TreeInfo, that seems to be more efficient but it returns null.

Input:

Program: nodeInfo.getTreeInfo().selectID("1", false); // returns null

I know, there must be a DTD that defines the attribute as being of type ID and the parser must be capable. However, without having a DTD, is it possible to get the element efficiently and how?

Thanks, Marc


Replies (4)

Please register to reply

RE: TreeInfo.selectId() to select element by ID efficiently - Added by Michael Kay almost 8 years ago

From your description, I assume there is nothing special about the ID attribute - the fact that it's name is "ID" obviously does not make it any different from any other attribute. Looking at the Saxon facilities for finding attributes of type ID isn't going to help if your ID attribute isn't an ID attribute, so to speak...

Assuming you are doing this often enough to justify the cost of building an index, then my suggestion would be to create a Java map.

Map map = new HashMap<>();
QName id = new QName("ID");
for (XdmItem n : xpathCompiler.evaluate("//*[@ID]") {
  XdmNode node = (XdmNode)n;
  map.put(n.getAttributeValue(id), node);
};

and then you can find nodes using the ID by looking in this map.

I can think of other techniques, e.g. building an XDM map rather than a Java map, but they will be a lot less efficient because they involve an XPath execution to find each ID value.

If you aren't doing this repeatedly, i.e. you only want to find one ID value, then the linear search is going to be the best method available.

Incidentally, if you need to evaluate something like @//[@ID = XXXX]@ repeatedly with different values of XXXX, then it's not a good idea to build the XPath expression by string concatenation. Remember that compiling an XPath expression usually costs much more than executing it. So compile the expression @//[@ID = $x]@ once, and then evaluate it repeatedly with different values of $x.

RE: TreeInfo.selectId() to select element by ID efficiently - Added by Marc Dzaebel almost 8 years ago

Great and helpfull answer,

in fact I have to use an XPathVariableResolver.

Thanks, Marc

RE: TreeInfo.selectId() to select element by ID efficiently - Added by Michael Kay almost 8 years ago

I'd recommend using the s9api interface for XPath evaluation, rather than the JAXP interface, because of its type safety, and its ability to handle the full XPath 2.0/3.0 data model, including for example maps and arrays.

    (1-4/4)

    Please register to reply