xsltproc vs XPath evaluate() method

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • A. W. Dunstan

    xsltproc vs XPath evaluate() method

    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.parse rs.*;
    import org.w3c.dom.*;
    import org.xml.sax.SAX Exception;
    import javax.xml.xpath .*;

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


    public XpathEval(Strin g filename)
    throws javax.xml.parse rs.ParserConfig urationExceptio n,
    SAXException,
    IOException
    {
    DocumentBuilder Factory dbf = DocumentBuilder Factory.newInst ance();
    DocumentBuilder db = dbf.newDocument Builder();
    m_doc = db.parse(new File(filename)) ;
    }

    public void evaluateXpath(S tring xpathExpr)
    throws XPathExpression Exception
    {
    XPathFactory f = XPathFactory.ne wInstance();
    XPath p = f.newXPath("/nuc2/Exer/ExerciseNicknam e");
    NodeList nl = (NodeList)p.eva luate(xpathExpr , m_doc,
    XPathConstants. NODESET);
    for (int i = 0; i < nl.getLength(); i++)
    System.out.prin tln(nl.item(i). getNodeName() + " -" +
    nl.item(i).getT extContent());
    }

    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:styleshe et xmlns:xsl="http ://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <xsl:template match="/">
    EXER/<xsl:value-of
    select="/nuc2/Exer/ExerciseNicknam e"/>/NICK:<xsl:value-of
    select="/nuc2/Exer/ExerciseAdditio nalIdentifier"/>//
    </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="//ExerciseNicknam e" 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:schemaLocat ion="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" >
    <ExerciseNickna me>pushups</ExerciseNicknam e>
    <ExerciseAdditi onalIdentifier> whatever</ExerciseAdditio nalIdentifier>
    </ns1:Exer>

    </ns2:nuc2>


    I'm giving it the same XPath expression in both cases
    ("/nuc2/Exer/ExerciseNicknam e") - 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

    #2
    Re: xsltproc vs XPath evaluate() method

    A. W. Dunstan wrote:
    DocumentBuilder Factory dbf = DocumentBuilder Factory.newInst ance();
    For XPath stuff you should always use a namespace aware factory/document
    builder so make sure you call the method to enable that.
    The XML source (src.xml, above) is:
    >
    <ns2:nuc2 xsi:schemaLocat ion="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" >
    <ExerciseNickna me>pushups</ExerciseNicknam e>
    <ExerciseAdditi onalIdentifier> whatever</ExerciseAdditio nalIdentifier>
    </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:styleshe et
    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/ExerciseNicknam e"/>

    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

    Comment

    • A. W. Dunstan

      #3
      Re: xsltproc vs XPath evaluate() method

      Martin Honnen wrote:
      A. W. Dunstan wrote:
      >
      > DocumentBuilder Factory dbf =
      > DocumentBuilder Factory.newInst ance();
      >
      For XPath stuff you should always use a namespace aware factory/document
      builder so make sure you call the method to enable that.
      >
      >The XML source (src.xml, above) is:
      >>
      ><ns2:nuc2 xsi:schemaLocat ion="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" >
      > <ExerciseNickna me>pushups</ExerciseNicknam e>
      > <ExerciseAdditi onalIdentifier> whatever</ExerciseAdditio nalIdentifier>
      > </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:styleshe et
      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/ExerciseNicknam e"/>
      >
      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

      Comment

      Working...