XML XPath

Poster Content
nk4um Administrator
Posts: 607
December 7, 2011 09:38

Hi Stefan, yes it's correct that getNodes doesn't do any cloning. The resulting nodes are still within the original structure. HDS is designed to be as light and memory efficient as possible so that's we made that design decision.

So yes you're spot on - in order to get a clone do something like this:

HDSBuilder b=new HDSBuilder();
b.importNode(nodeData);
IHDSNode newNodeData=b.getRoot();

Cheers, Tony

Like · Post Reply
nk4um User
Posts: 90
December 7, 2011 09:19

hi,

from your answers i see that i missed the point of my problem, sorry for that:

while(iter.hasNext()) {
   nodeData = iter.next();

   // put nodeData on the scratchpad for later use
   req = context.createRequest("scratch:textElement");
   req.setVerb(INKFRequestReadOnly.VERB_SINK);
   req.addPrimaryArgument(nodeData);
   context.issueRequest(req);  
   
   // start another script that uses the scratchpad entry //somewhere in it's workflow
   ... 
}

When the scratchpad entry 'textElement' is sourced somewhere later in the workflow, the XPath '//outlineID' again yields the same exception 'to many nodes'.

It looks like that the hdsNode.getNodes("..") method doesn't return a list of independent or new HDSNode objects but somehow references to the original HDSNode. Is this correct? A possible solution could be to use HDSBuilder to create a new HDSNode and import the children of the desired node.

thanks, Stefan

Like · Post Reply
nk4um Administrator
Posts: 607
December 6, 2011 20:13

Hi Stefan, Tom,

I think this may be a bug. See:

http://localhost:1060/book/view/book:coremeta/doc:coremeta:hds:hdsxpath

We make the assumption that // starts at the root if it isn't preceded by a node name. HDS doesn't have a complete xpath implementation just a limited easy to parse subset. I'll look at fixing this and report back. Sorry for the inconvenience.

Cheers, Tony

Like · Post Reply
nk4um User
Posts: 131
December 6, 2011 19:13

Greetings Stefan,

It is strange and I haven't thought of a "why" yet. However, two small changes to your code : req.addArgument("operator", "outlineID");

1) ID -> two capitals in your data, two capitals in your XPath. I assume that was an error you already found ? 2) We want the node outlineID in the current node, the // are not needed then.

This works for me, let me know if it works for you. I'll get back later with an explanation why //outlineID is not working.

Regards, Tom

Like · Post Reply
nk4um User
Posts: 90
December 6, 2011 13:07

hello Tom,

XPath has made it's way into the XML module, thank you for that. In the meantime i made my experiences with XML and that are the conclusions i figured out for my work:

  1. with nCode HDSXPath oder XPath is the convenient way if i don't want to use an external resource like an XSL stylesheet
  2. if things get complicated i use active:xslt
  3. with resources like scripts i use active:xslt if i get along with the XSL syntax or a DOMXDA object which is sometimes easier to handle. Together with some XML utilities or the practical XMLReadable, which i found by incident, there is everything to do the work
  4. i mixed up Netkernel/ROC and XML processing: ROC is the base but is not a XML tool. XML is covered by some modules and in the basic APIs like layer0. So reading the API and looking at the Netkernel java code to get examples of usage is the best thing to handle XML workflow. If i have a wish: add more explanations to the javadoc and some best practices to use it.
  5. i'm still experimenting what's the best way to pass information around: HDS, a DOMXDA object or a binaryStream. All solutions work and have their merits. Problems occur with adding new parts and the need to add new information. HDS seems the most flexible way for this(only one thing i can't get right at the moment, see below)

The HDSNode made with HDSBuilder:

<hds>
  <textElement>
    <text>. . .&lt;/text&gt;
    <outlineID>1&lt;/outlineID&gt;
  &lt;/textElement&gt;
  <textElement>
    <text>. . .&lt;/text&gt;
    <outlineID>2&lt;/outlineID&gt;
  &lt;/textElement&gt;
  <textElement>
    <text>. . .&lt;/text&gt;
    <outlineID>3&lt;/outlineID&gt;
  &lt;/textElement&gt;
&lt;/hds&gt;

The pseudo code to get the single <texElement> nodes:

[...]
IHDSNodeList list = hdsNode.getNodes("//textElement");
Iterator iter =list.iterator();

while(iter.hasNext()) {
   nodeData = iter.next();

   System.out.println(nodeData);

   // get value of the outlineID
   req = context.createRequest("active:HDSXpath");
   req.addArgumentByValue("operand", nodeData);
   req.addArgument("operator", "//outlineId");
   result = context.issueRequest(req); 

...
}

Printing out nodeData gives exactly one node like expected. But using the active:HDSXpath yields an exception:

<ex>
  <ex>
    <id>RequestFrameException&lt;/id&gt;
    <request> SOURCE active:HDSXpath+operand@pbv%3Aoperand+operator@//outlineId as Object &lt;/request&gt;
  &lt;/ex&gt;
  <ex>
    <id>SubrequestException&lt;/id&gt;
    <spaceHash>MW/7&lt;/spaceHash&gt;
    <space>Layer 1&lt;/space&gt;
    <endpoint>HDSXpathAccessor&lt;/endpoint&gt;
    <endpointHash>MW/7/qp&lt;/endpointHash&gt;
    <logicalEndpointHash>MW/7/ep:OQN2GE-B7NNJ0&lt;/logicalEndpointHash&gt;
    <logicalEndpoint>HDSXpathAccessor&lt;/logicalEndpoint&gt;
    <ex>
      <id>Multiple nodes found, expected one&lt;/id&gt;
      <location>//outlineId&lt;/location&gt;
    &lt;/ex&gt;
  &lt;/ex&gt;
&lt;/ex&gt;

The HDSXpath is applied to the whole hdsNode, not to the first <textElement> node as it should be. Is this the expected behavior?

thanks, Stefan

Like · Post Reply
nk4um User
Posts: 131
November 15, 2011 10:26

Stefan,

It used to be that I could contact you directly through the forums, but I don't see it here. Anyway, my emailadres is tom<dot>geudens<at>hush<dot>ai. Can you send me your coordinates and I'll send you an adapted XML Core module to use while the module is being revised/tested/approved.

Regards, Tom

Like · Post Reply
nk4um User
Posts: 90
November 15, 2011 10:16

hi Tom,

yes, that is exactly what i just planned to do: writing my own accessor utilizing org.netkernel.layer0.util.XPath. it would be great if you can implement a standard Netkernel tool. there might be some considerations i'm not aware of.

thanks a lot, Stefan

Like · Post Reply
nk4um User
Posts: 131
November 15, 2011 10:01proposal XPathSnippet

Greetings once more Stefan,

Would this cover your need ?

If so, I'll propose this little tool to our friends at 1060 Research.

Regards, Tom

Like · Post Reply
nk4um User
Posts: 131
November 15, 2011 09:02saxon xpath

Greetings Stefan,

I've been informed (the European community is waking up ;-) that Saxon XPath would also cover your needs ! However, it would mean another import ... and if I'm correct (check this) Saxon's license is not that liberal.

I'll fix you a tool as I promised. If not for you it might be useful for somebody else. Does the XSLT work for you in the mean time ?

Regards, Tom

Like · Post Reply
nk4um User
Posts: 131
November 15, 2011 08:52FastXPath

Greetings Stefan,

The example module uses an nCoDE endpoint :

I can see what you are trying to do. Now, XSLT is in the same library that you already need to include (core.xml), for the only available nCoDE tool that uses the FastXPath you mention is XPathEval. And that doesn't fit your jobdescription, for it returns a boolean, not the snippet you want.

The only tool that does do what you want is XSLT. At the moment that is. For the FastXPath may indeed be put to other use. I'll see if I can make a tool for you, but at the moment XSLT is the only tool that fits the job (I think, I could be wrong ;-).

Regards, Tom

Like · Post Reply
nk4um User
Posts: 90
November 15, 2011 08:29

Hi Tom,

thnak you for the answer! i have also considered that, but as Netkernel relies heavily on XML i thought that there must be an more elegant solution. also i use the nCode environment and want to do as much as possible without external scripts or code. there is a HDSFilter endpoint that should do the work but i can't figure out how. in thread HDS vs. XDA HDSPredicate filtering is mentioned, but how to do it without an external script which i want to avoid?

thanks, Stefan

Like · Post Reply
nk4um User
Posts: 131
November 15, 2011 06:57example available

Greetings Stefan,

If you require an example module for the above, let me know, I've got one ready.

Regards, Tom

Like · Post Reply
nk4um User
Posts: 131
November 15, 2011 04:52

Greetings Stefan,

I would use XSLT to do the trick. This would be the template :

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:nk="http://netkernel.org" version="1.0">
  <xsl:outputmethod="xml" indent="yes" encoding="UTF-8" /&gt;
  <xsl:templatematch="/config">
    <config>
      <xsl:copy-ofselect="build[@target='ciiema-user']" /&gt;
    &lt;/config&gt;
  &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;

Does that help ?

Regards, Tom

Like · Post Reply
nk4um User
Posts: 90
November 14, 2011 23:23XML XPath

Hi,

i have a simple question: which is the easiest way to get a node from an xml based on XPath. I'm trying to do it with nCode and don't want to use a groovy script.

This is the xml:

<config>
  <buildtarget="ciiema-user">
    <target>ciiema-user&lt;/target&gt;
    <path>file:///H:/stefan/citem.ciiema&lt;/path&gt;
    <config-file>ciiema-manuals-config.xml&lt;/config-file&gt;
  &lt;/build&gt;
  <buildtarget="ciiema-admin">
    <target>ciiema-user&lt;/target&gt;
    <path>file:///H:/stefan/citem.ciiema&lt;/path&gt;
    <config-file>ciiema-manuals-config.xml&lt;/config-file&gt;
  &lt;/build&gt;
&lt;/config&gt;

the XPath looks like

 /build[@target='ciiema-user']

HDSXPath doesn't work because only integer predicates are allowed. Maybe HDSFilter is a solution, but i can't figure it out how to use is. the nCode block has 3 arguments (operand, cond, node) but in the documentation 'node' isn't mentioned. (btw, could you add an usage example to every documentation? it would make life easier.)

thanks,

Stefan

Like · Post Reply