0

Can you get the text() of a jxpath element or does it not work?

given some nice xml:

<?xml version="1.0" encoding="UTF-8"?>
<AXISWeb xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="AXISWeb.xsd">
    <Action>
    <Transaction>PingPOS</Transaction>
    <PingPOS>
        <PingStep>To POS</PingStep> 
        <PingDate>2012-11-15</PingDate> 
        <PingTime>16:35:57</PingTime> 
    </PingPOS>
    <PingPOS>
        <PingStep>POS.PROCESSOR18</PingStep> 
        <PingDate>2012-11-15</PingDate> 
        <PingTime>16:35:57</PingTime> 
    </PingPOS>
    <PingPOS>
        <PingStep>From POS</PingStep> 
        <PingDate>2012-11-15</PingDate> 
        <PingTime>16:35:57</PingTime> 
    </PingPOS>
</Action>
</AXISWeb>

//Does not work:

jxpc.getValue("/AXISWeb/Action/PingPOS[1]/PingStep/text()");

//Does not work:

jxpc.getValue("/action/pingPOS[1]/PingStep/text()");

//Does not work:

jxpc.getValue("/action/pingPOS[1]/PingStep[text()]");

I know I can get the text from using

jxpc.getValue("/action/pingPOS[1]/PingStep");

But that's not the point. Shouldn't text() work? I could find no examples....

P.S. It's also very very picky about case and capitalization. Can you turn that off somehow?

Thanks, -G

ggb667
  • 1,881
  • 2
  • 20
  • 44

2 Answers2

2

/AXISWeb/Action/PingPOS[1]/PingStep/text() is valid XPath for your document

But, from what I can see from the user guide of jxpath (note: I don't know jxpath at all), getValue() is already supposed to return the textual content of a node, so you don't need to use the XPath text() at all.

So you may use the following:

jxpc.getValue("/AXISWeb/Action/PingPOS[1]/PingStep");

Extracted from the user guide:

Consider the following XML document:

<?xml version="1.0" ?>
<address>
  <street>Orchard Road</street>
</address> 

With the same XPath, getValue("/address/street"), will return the string "Orchard Road", while selectSingleNode("/address/street") - an object of type Element (DOM or JDOM, depending on the type of parser used). The returned Element is, of course, <street>Orchard Road</street>.

Now about case insensitive query on tag names, if you are using XPath 2 you can use lower-case() and node() but this is not really recommended, you may better use correct names.

/*[lower-case(node())='axisweb']/*[lower-case(node())='action']/...

or if using XPath 1, you may use translate() but it gets even worse:

/*[translate(node(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz') = 'axisweb']/*[translate(node(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz') = 'action']/...

All in all, try to ensure that you use correct query, you know it is case sensitive, so it's better to pay attention to it. As you would do in Java, foo and fOo are not the same variables.


Edit:

As I said, XML and thus XPath is case sensitive, so pingStep cannot match PingStep, use the correct name to find it.

Concerning text(), it is part of XPath 1.0, there is no need for XPath 2 to use it. The JXPath getValue() is already doing the call to text() for you. If you want to do it yourself you will have to use selectSingleNode("//whatever/text()") that will returns an Object of type TextElement (depending on the underlying parser).

So to sum up, the method JXPathContext.getValue() already does the work to select the node's text content for you, so you don't need to do it yourself and explicitly call XPath's text().

Alex
  • 25,147
  • 6
  • 59
  • 55
  • Though it may be valid it does not work. I get null (unless lenient is off), else I get an exception. Also /action/pingPOS[1]/PingStep/text() give me null. Also the A in Action and the P in PingPOS have to be lowercase, but the PingStep has to be the case it is or it does not work. This does not make for an easy to use interface! The top level /AXISWeb never seems to work. – ggb667 Nov 15 '12 at 22:23
  • What about `//PingPOS[1]/PingStep` ? – Alex Nov 16 '12 at 06:34
  • Well //PingPOS[1]/PingStep gets "To POS" IF I change the case to be bean like: //pingPOS[1]/pingStep (Note Not capital "P" in both PingPOS and PingStep). But the question is why does text() not work. Is text part of xpath 2.0? I was pretty sure it was part of xpath 1.0. Can I not get the entire slot of XML within a tag - To POS2012-11-1516:35:57 for example? Maybe I want to return a piece of XML. – ggb667 Nov 16 '12 at 16:46
1

From a post that I've anserwed before the method .getTextContent() do the job for you. No need to use "text()" when you evaluate the Xpath.

Example :

Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("D:\\Loic_Workspace\\Test2\\res\\test.xml"));


    System.out.println(doc.getElementsByTagName("retCode").item(0).getTextContent());

If not, you will get the tag and the value. If you want do more take a look at this

ggb667
  • 1,881
  • 2
  • 20
  • 44