Sign In | Register Now About Bytes | Help | Site Map
Connecting Tech Pros Worldwide

xsltproc vs XPath evaluate() method

Question posted by: A. W. Dunstan (Guest) on June 27th, 2008 07:07 PM
I'm trying to figure out how XPath expressions work, and how I can use them
to extract data into a particular format. I can extract the data I want
using an XPath expression, but not with an XSLT stylesheet. Here's the
Java/XPath I'm using:


import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import javax.xml.xpath.*;

public class XpathEval
{
public static void main(String []args)
{
try {
XpathEval loader = new XpathEval("src.xml");
loader.evaluateXpath();
}
catch(Exception e) {
System.out.println(e);
}
}


public XpathEval(String filename)
throws javax.xml.parsers.ParserConfigurationException,
SAXException,
IOException
{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
m_doc = db.parse(new File(filename));
}

public void evaluateXpath(String xpathExpr)
throws XPathExpressionException
{
XPathFactory f = XPathFactory.newInstance();
XPath p = f.newXPath("/nuc2/Exer/ExerciseNickname");
NodeList nl = (NodeList)p.evaluate(xpathExpr, m_doc,
XPathConstants.NODESET);
for (int i = 0; i < nl.getLength(); i++)
System.out.println(nl.item(i).getNodeName() + " -" +
nl.item(i).getTextContent());
}

private Document m_doc;
}


However, if I try to extract & format the data via xsltproc it doesn't
extract the data. Here's the command I use:

xsltproc xsltStyleSheet.xsl src.xml

with the following for xsltStyleSheet.xsl:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

<xsl:template match="/">
EXER/<xsl:value-of
select="/nuc2/Exer/ExerciseNickname"/>/NICK:<xsl:value-of
select="/nuc2/Exer/ExerciseAdditionalIdentifier"/>//
</xsl:template>

</xsl:stylesheet>



Instead of printing out what I expect (the odd format is a requirement for
what I'm trying to convert it to):

EXER/pushups/NICK:whatever//

it prints this:

EXER//NICK://

If I change the XPath expression in my XSLT stylesheet to
select="//ExerciseNickname" then it works. But in the full XML file there
are places where that won't work - there's /a/b/fieldname
and /x/y/fieldname and I want exactly one of them. I suppose I could make
that work, but I'd like to know what I'm doing wrong.

The XML source (src.xml, above) is:

<ns2:nuc2 xsi:schemaLocation="nuc2.xsd" xmlns:ns1="Exer_Sets"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="nuc2">

<ns1:Exer SetSequence="1" SetDescription="Exercise Identification">
<ExerciseNickname>pushups</ExerciseNickname>
<ExerciseAdditionalIdentifier>whatever</ExerciseAdditionalIdentifier>
</ns1:Exer>

</ns2:nuc2>


I'm giving it the same XPath expression in both cases
("/nuc2/Exer/ExerciseNickname") - one finds what I'm looking for, the other
doesn't. I'm using Java 1.6.0_05 on Fedora 8. xsltproc comes from the
libxslt package, version 1.1.24.

Any clues?

thanks!

--
Al Dunstan, Software Engineer
OptiMetrics, Inc.
3115 Professional Drive
Ann Arbor, MI 48104-5131
Martin Honnen's Avatar
Martin Honnen
Guest
n/a Posts
June 27th, 2008
07:07 PM
#2

Re: xsltproc vs XPath evaluate() method
A. W. Dunstan wrote:
Quote:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();


For XPath stuff you should always use a namespace aware factory/document
builder so make sure you call the method to enable that.
Quote:
The XML source (src.xml, above) is:
>
<ns2:nuc2 xsi:schemaLocation="nuc2.xsd" xmlns:ns1="Exer_Sets"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="nuc2">
>
<ns1:Exer SetSequence="1" SetDescription="Exercise Identification">
<ExerciseNickname>pushups</ExerciseNickname>
<ExerciseAdditionalIdentifier>whatever</ExerciseAdditionalIdentifier>
</ns1:Exer>
>
</ns2:nuc2>


So your XML uses namespaces, to cater for that the XSLT stylesheet needs
to bind prefixes to the namespaces used:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:ns2="nuc2"
xmlns:ns1="Exer_Sets"
exclude-result-prefixes="ns1 ns2">
then you need to use those prefixes in your XPath expressions and in
your XSLT match patterns:

<xsl:value-of select="/ns2:nuc2/ns1:Exer/ExerciseNickname"/>

You just got lucky with your Java program as you used a not namespace
aware DOM I think, if you use a namespace aware DOM then you need
prefixes in your XPath expressions too and need to manage them in your
Java program too.


--

Martin Honnen
http://JavaScript.FAQTs.com/

A. W. Dunstan's Avatar
A. W. Dunstan
Guest
n/a Posts
June 27th, 2008
07:07 PM
#3

Re: xsltproc vs XPath evaluate() method
Martin Honnen wrote:
Quote:
A. W. Dunstan wrote:
>
Quote:
> DocumentBuilderFactory dbf =
> DocumentBuilderFactory.newInstance();

>
For XPath stuff you should always use a namespace aware factory/document
builder so make sure you call the method to enable that.
>
Quote:
>The XML source (src.xml, above) is:
>>
><ns2:nuc2 xsi:schemaLocation="nuc2.xsd" xmlns:ns1="Exer_Sets"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xmlns:ns2="nuc2">
>>
> <ns1:Exer SetSequence="1" SetDescription="Exercise Identification">
> <ExerciseNickname>pushups</ExerciseNickname>
> <ExerciseAdditionalIdentifier>whatever</ExerciseAdditionalIdentifier>
> </ns1:Exer>
>>
></ns2:nuc2>

>
So your XML uses namespaces, to cater for that the XSLT stylesheet needs
to bind prefixes to the namespaces used:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:ns2="nuc2"
xmlns:ns1="Exer_Sets"
exclude-result-prefixes="ns1 ns2">
then you need to use those prefixes in your XPath expressions and in
your XSLT match patterns:
>
<xsl:value-of select="/ns2:nuc2/ns1:Exer/ExerciseNickname"/>
>
You just got lucky with your Java program as you used a not namespace
aware DOM I think, if you use a namespace aware DOM then you need
prefixes in your XPath expressions too and need to manage them in your
Java program too.


It works! Much thanks. I'll go read up on namespaces.

--
Al Dunstan, Software Engineer
OptiMetrics, Inc.
3115 Professional Drive
Ann Arbor, MI 48104-5131

 
Not the answer you were looking for? Post your question . . .
189,798 Experts ready to help you find a solution.
Sign up for a free account, or Login (if you're already a member).

Latest Articles: Read & Comment
  • Didn't find the answer you were looking for?
    Post Your Question
  • Top Community Contributors