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