Project

Profile

Help

JAVA: Dom4J expression getUniquePath in SAXON

Added by Mario Mueller almost 6 years ago

Hi all,

in Dom4J I get the unique path example /M_UTILMD/G_SG4[1]/S_DTM[4]/D_2380 with the method Node.getUniquePath() Could pls anybody tell what the corresponding expression in SAXON is?

Many Thanks Regards Mario


Replies (6)

Please register to reply

RE: JAVA: Dom4J expression getUniquePath in SAXON - Added by Mario Mueller almost 6 years ago

Sorry hete the Expression in code


parentNode.getUniquePath()

RE: JAVA: Dom4J expression getUniquePath in SAXON - Added by Mario Mueller almost 6 years ago

sorry, sorry; I hope this will be the last time

uniquePath example:


 /M_UTILMD/G_SG4[1]/S_DTM[4]/D_2380

RE: JAVA: Dom4J expression getUniquePath in SAXON - Added by Michael Kay almost 6 years ago

The main challenge with getting a usable path expression for a node is what to do about namespaces. I've no idea how the DOM4J getUniquePath() method solves that problem.

Saxon offers the XPath 3.0 function fn:path(), which solves that issue using EQNames.

If you want to invoke that directly from Java, at the s9api level, you could do XdmFunctionItem.getSystemFunction(....).call(....);

RE: JAVA: Dom4J expression getUniquePath in SAXON - Added by Mario Mueller almost 6 years ago

Hi Michael,

to make it clear: I got a program where I used dom4j.

With dom4j I can select nodes using the following expression/example


ListNodeList = document.selectNodes("/M_UTILMD/G_SG4/S_DTM/C_C507/D_2005");

This expression provides a NodeList. Now I can loop over this NodeList to get the unique paths:


			for (Iterator iterator = NodeList .iterator(); iterator.hasNext();) {
				Node node = (Node) iterator.next();
				 System.out.println(node.getUniquePath());

			}

The output will look like:


/M_UTILMD[1]/G_SG4[1]/S_DTM[1]/C_C507[1]/D_2005[1]
/M_UTILMD[1]/G_SG4[1]/S_DTM[2]/C_C507[1]/D_2005[1]
/M_UTILMD[1]/G_SG4[1]/S_DTM[3]/C_C507[1]/D_2005[1]
/M_UTILMD[1]/G_SG4[2]/S_DTM[1]/C_C507[1]/D_2005[1]
/M_UTILMD[1]/G_SG4[3]/S_DTM[1]/C_C507[1]/D_2005[1]

Here I'd like to know the analog expression in SAXON.

Regards Mario

RE: JAVA: Dom4J expression getUniquePath in SAXON - Added by Michael Kay almost 6 years ago

Well, I was trying to explain, I can't see from the DOM4J Javadoc what the precise specification of DOM4J's getUniquePath() is, and that makes it hard to suggest an alternative way of getting the same result. In particular, what does getUniquePath() do when it finds elements that are in a namespace?

How are you using these paths? Are they for human consumption, or are they for evaluation using an XPath engine? (that choice has a profound effect on how you handle namespaces).

There's nothing directly analogous in Saxon's Java API, but if you can tell me exactly what's needed, then I'm sure we can devise an XPath expression that delivers it. If you want a path that is suitable for evaluation by an XPath engine, then the XPath 3.0 fn:path() function meets the requirement, although it won't give you exactly the same output as the getUniquePath() method. If you want something intended for a human reader, then a recursive XQuery function like this might be the answer:

declare function local:getUniquePath($n as node()) as xs:string {
   concat(
     if ($n/parent::*) then local:getUniquePath($n/parent::*) else "",
     name($n),
     if ($n/preceding-sibling::*[name() = name($n)]) then concat('[', count($n/preceding-sibling::*[name() = name($n)]+1, ']' else ""
   )
};

RE: JAVA: Dom4J expression getUniquePath in SAXON - Added by Mario Mueller almost 6 years ago

Hi Michael,

many thanks. I got a solution:



		try {
			XPathSelector xpathSel = xPathCompiler.compile(<<>>>+ "/path(.)").load();
			xpathSel.setContextItem(xdmdocument);

			// Do not delete: For debugging
			for (XdmValue val : xpathSel.evaluate()) {
				if (excelRow.number.equalsIgnoreCase(StopAtLine)) {
					String UniquePath = val.toString().replace("Q{}", "");
					System.out.println(UniquePath);
				}
			}

Regards Mario

    (1-6/6)

    Please register to reply