You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by Wei Cheng <We...@baylor.edu> on 2000/11/05 01:00:52 UTC

Sorry for Repost for asking Xpath question.

Hi All,
 I have tried to use Xalan package to do my master's project.
 First, I write a primary key fuction to try to test whether XMl
 document can satisfy the primary key requirement.
 I modify the example ApplyXpath.java and foo.xml to test my idea.
 I use foo1.xml as an XMl document input.
<?xml version="1.0"?>
<doc>
  <name>
    <firstname> David </firstname>
    <lastname> Marston</lastname>
  </name>
  <name>
    <firstname> David  </firstname>
    <lastname> Bertoni </lastname>
  </name>
  <name>
    <firstname> Donald  </firstname>
    <lastname> Leslie </lastname>
  </name>
   <name>
    <firstname> Emily  </firstname>
    <lastname> Farmer </lastname>
  </name>
   <name>
    <firstname> Jack  </firstname>
    <lastname> Donohue</lastname>
  </name>
   <name>
    <firstname> Myriam  </firstname>
    <lastname> Midy</lastname>
  </name>
   <name>
    <firstname> Paul </firstname>
    <lastname> Dick</lastname>
  </name>
   <name>
    <firstname> Robert </firstname>
    <lastname> Weir</lastname>
  </name>
  <name>
    <firstname> Scott </firstname>
    <lastname> Boag</lastname>
  </name>
   <name>
    <firstname> Shane </firstname>
    <lastname> Curcuru</lastname>
  </name>
</doc>
and I change ApplyXPath.java to MyXpath.java
// This file uses 4 space indents, no tabs.

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import org.apache.xerces.parsers.DOMParser;
import org.apache.xpath.XPathAPI;
//import org.apache.xpath.xml.FormatterToXML;
import org.apache.xalan.utils.TreeWalker;
import org.apache.xalan.utils.DOMBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;
import org.apache.xpath.NodeSet; //import NodeSet
import org.apache.xalan.lib.Extensions; // import Extensions for NodeSet
import org.w3c.dom.NodeList;
import org.w3c.dom.traversal.NodeIterator;
//import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.InputSource;

// Imported JAVA API for XML Parsing 1.0 classes
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

// Imported Serializer classes
import org.apache.serialize.OutputFormat;
import org.apache.serialize.Serializer;
import org.apache.serialize.SerializerFactory;
import org.apache.xml.serialize.transition.XMLSerializer;
import org.apache.xml.serialize.transition.TextSerializer;

/**
 *  Very basic utility for applying an XPath epxression to an xml file and printing information
/  about the execution of the XPath object and the nodes it finds.
 *  Takes 1 argument:
 *     (1) an xml filename
 *  Examples:
 *     java MyXPath foo1.xml /
 */
public class MyXPath
{
    protected String filename = null;
    protected String xpath = "/doc/name/firstname";
    //suppose firname is a primary key attribute
    Document doc = null;
    Element root = null;
    String part1=null;
    String part2=null;
    /** Process input args and execute the XPath.  */
    public void getDocument(String[] args)
    {
        filename = args[0];
        if (filename != null)
        {
            InputSource in;
            try
            {
                in = new InputSource(new FileInputStream(filename));
            }
            catch (FileNotFoundException fnf)
            {
                System.err.println("FileInputStream of " + filename + " threw: " + fnf.toString());
                fnf.printStackTrace();
                return;
            }

            try
            {
                DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
                doc = docBuilder.parse(in);
                root = doc.getDocumentElement();
            }
            catch (ParserConfigurationException pce)
            {
                pce.printStackTrace();
            }
            catch(Exception e1)
            {
                System.err.println("Parsing " + filename + " threw: " + e1.toString());
                e1.printStackTrace();
                return;
            }
        }
    }
    public boolean primarykey()
    {
        System.out.println(xpath);
         NodeIterator ni1 = null;
        try
        {
            // Use the simple XPath API to select a nodeIterator.
            ni1 = XPathAPI.selectNodeIterator(doc, xpath);
        }
        catch (Exception e2)
        {
            System.err.println("selectNodeIterator threw: " + e2.toString() + " perhaps your xpath didn't select any
nodes");
            e2.printStackTrace();
            return false;
        }
        NodeSet ns1=new NodeSet(ni1); // change from nodeiterator to nodeset
         Node n=ns1.item(0);
          String x2=new String("/doc/name[1]/following-sibling::name/firstname");
          //get the following-sibling of the name[1]
            NodeIterator ni2 = null;
            try
            {
                // Use the simple XPath API to select a nodeIterator.
                ni2 = XPathAPI.selectNodeIterator(doc, x2);
            }
            catch (Exception e2)
            {
                System.err.println("selectNodeIterator threw: " + e2.toString() + " perhaps your xpath didn't select any
nodes");
                e2.printStackTrace();
                return false;
            }
            NodeSet ns2=new NodeSet(ni2); // change from nodeiterator to nodeset
            if (ns2.contains(n))    // in my case because the name[2]
            //firstname is the same as name[1], so has duplicate node
            // "David" for firstname  but cann't find duplicate node
             {
              System.out.println("dupicate node found");
             return false;
        }          
        return true;

    }
    /** Main method to run from the command line.    */
    public static void main (String[] args)
    {
        if (args.length != 1)
        {
            System.out.println("java MyXPath filename.xml \n"
            + "Reads filename.xml ");
            return;
        }
        MyXPath app = new MyXPath();
        app.getDocument(args);
        if (app.primarykey())
          System.out.println("is a primary key");
        else 
          System.out.println("is not a primary key");
    }

} // end of class MyXPath

 When I tried to test this program, I always get the answer "is a
 primary key", I don't know how to realize contains function.
 hopefully somebody can give me a help.
  

Best regards,
 Wei                          mailto:Wei_Cheng@baylor.edu



ask another question

Posted by Wei Cheng <We...@baylor.edu>.
Hi Gary,

Thursday, November 09, 2000, 10:14:42 PM, you wrote:

GLP> Wei Cheng wrote:
>> 
>> Hi All,
>>  I have tried to use Xalan package to do my master's project.
>>  First, I write a primary key fuction to try to test whether XMl
>>  document can satisfy the primary key requirement.
>>  I modify the example ApplyXpath.java and foo.xml to test my idea.
>>  I use foo1.xml as an XMl document input.
>>  ...

GLP> Wei --

GLP> Did you ever get an answer on this?  If you're trying to do this compare
GLP> in java, I think you can just iterate over the NodeSets with one loop
GLP> nested inside the other.

GLP> BTW, I'd stay away from NodeSet because this is a Xalan invention that
GLP> could change.  NodeSet also extends NodeList which is a DOM class and I
GLP> think you'd be better off using that or NodeIterator.

GLP> You could also do this entirely with your XPath.  You currently have the
GLP> second XPath as 

GLP>         /doc/name[1]/following-sibling::name/firstname

GLP> I think you could make it something like

GLP>         /doc/name[1]/following-sibling::name/firstname[. !=
GLP> /doc/name[1]/firstname]

GLP> Then, you'd only have one XPath and you'd just have to check if the
GLP> resulting node-set was null or not.  If you wanted, you could loop
GLP> through this for each name in doc and dynamically build an XPath,
GLP> changing the subscript in your java program.

GLP> Or, you could use XPath alone to just get a node-set containing all of
GLP> the name elements that contain what you call primary keys:

GLP>         /doc/name[firstname != preceding-sibling::name/firstname]

GLP> Haven't tested these expressions, but they should be close.

GLP> Gary

   Thanks a lot first! I have tried all these two expressions, for the
   second one   /doc/name[firstname !=
   preceding-sibling::name/firstname],
   it seems that I can't get the /doc/name[1]/firstname when I apply
   Xpath, I want to test a set of firstname in the doc to see whether
   all firstname are different,if yes,I return yes otherwise return
   false.
   this is my strategy:
   If I can get NodeIterator when I apply second Xpath, and
   compare with another NodeIterator when I apply /doc/name/firstname,
   and I compare each node in these two nodeiterators, to see if the node
   order and the value is the same, then return true else false.
   but for some reason, /doc/name[1]/firstname doesn't show in the
   nodeiterator when I apply second Xpath from you. From the
   definition,it should be here. because the /doc/name[1]/firstname's
   preceding-sibling should be null.
   Can you give me some advice on this or give me other idea for this?
   Thanks again!

Best regards,
 Wei                            mailto:Wei_Cheng@baylor.edu



Re: Sorry for Repost for asking Xpath question.

Posted by Gary L Peskin <ga...@firstech.com>.
Wei Cheng wrote:
>    What I want is to try to write an deepCompare for the node and
>    deepContains for the nodeset to solove primary key function.
>    Is it worth doing this and expand the xalan package?
>    Thanks again!

I think you're better off doing this with standard XSLT techniques like
I mentioned.  But others may have a need for deepCompare and
deepContains.  If so, I'm sure they'll let you know.

Gary

Re[2]: Sorry for Repost for asking Xpath question.

Posted by Wei Cheng <We...@baylor.edu>.
Hi Gary,

Thursday, November 09, 2000, 10:14:42 PM, you wrote:

GLP> Wei Cheng wrote:
>> 
>> Hi All,
>>  I have tried to use Xalan package to do my master's project.
>>  First, I write a primary key fuction to try to test whether XMl
>>  document can satisfy the primary key requirement.
>>  I modify the example ApplyXpath.java and foo.xml to test my idea.
>>  I use foo1.xml as an XMl document input.
>>  ...

GLP> Wei --

GLP> Did you ever get an answer on this?  If you're trying to do this compare
GLP> in java, I think you can just iterate over the NodeSets with one loop
GLP> nested inside the other.

GLP> BTW, I'd stay away from NodeSet because this is a Xalan invention that
GLP> could change.  NodeSet also extends NodeList which is a DOM class and I
GLP> think you'd be better off using that or NodeIterator.

GLP> You could also do this entirely with your XPath.  You currently have the
GLP> second XPath as 

GLP>         /doc/name[1]/following-sibling::name/firstname

GLP> I think you could make it something like

GLP>         /doc/name[1]/following-sibling::name/firstname[. !=
GLP> /doc/name[1]/firstname]

GLP> Then, you'd only have one XPath and you'd just have to check if the
GLP> resulting node-set was null or not.  If you wanted, you could loop
GLP> through this for each name in doc and dynamically build an XPath,
GLP> changing the subscript in your java program.

GLP> Or, you could use XPath alone to just get a node-set containing all of
GLP> the name elements that contain what you call primary keys:

GLP>         /doc/name[firstname != preceding-sibling::name/firstname]

GLP> Haven't tested these expressions, but they should be close.

GLP> Gary

   Thanks for your advice! I'll try it. What I think that because the
   Node comparision in java is use Object.equals in the source code
   (contains) function,and for comparing Object in java is compare the
   hashcode of the object,so even the two node's ( subtree attribute and
   content is the same),it is not equal in java equals function for
   different hashcode.
   What I want is to try to write an deepCompare for the node and
   deepContains for the nodeset to solove primary key function.
   Is it worth doing this and expand the xalan package?
   Thanks again!
Best regards,
 Wei                            mailto:Wei_Cheng@baylor.edu



Re: Sorry for Repost for asking Xpath question.

Posted by Gary L Peskin <ga...@firstech.com>.
Wei Cheng wrote:
> 
> Hi All,
>  I have tried to use Xalan package to do my master's project.
>  First, I write a primary key fuction to try to test whether XMl
>  document can satisfy the primary key requirement.
>  I modify the example ApplyXpath.java and foo.xml to test my idea.
>  I use foo1.xml as an XMl document input.
>  ...

Wei --

Did you ever get an answer on this?  If you're trying to do this compare
in java, I think you can just iterate over the NodeSets with one loop
nested inside the other.

BTW, I'd stay away from NodeSet because this is a Xalan invention that
could change.  NodeSet also extends NodeList which is a DOM class and I
think you'd be better off using that or NodeIterator.

You could also do this entirely with your XPath.  You currently have the
second XPath as 

	/doc/name[1]/following-sibling::name/firstname

I think you could make it something like

	/doc/name[1]/following-sibling::name/firstname[. !=
/doc/name[1]/firstname]

Then, you'd only have one XPath and you'd just have to check if the
resulting node-set was null or not.  If you wanted, you could loop
through this for each name in doc and dynamically build an XPath,
changing the subscript in your java program.

Or, you could use XPath alone to just get a node-set containing all of
the name elements that contain what you call primary keys:

	/doc/name[firstname != preceding-sibling::name/firstname]

Haven't tested these expressions, but they should be close.

Gary