On Sun, Aug 02, 2009 at 12:50:05AM +0900, Matt Neuburg wrote: > Stanislaw Wozniak <stan / wozniak.com> wrote: > > > Hi, this was a typo, no semicolon in there: > > > > <?xml version="1.0" encoding="UTF-8"?> > > <configuration-data > > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > > xsi:schemaLocation="urn:company:platform:foundation:configuration:defn:v1" > > xmlns="urn:company:platform:foundation:configuration:defn:v1"> > > <attributeList> > > <attribute name="siteid" validationRuleName="String" description="Site > > id"> > > <tree name="siteid_hierarchy"> > > <treenode name="Root"> > > <treenode name="1" /> > > </treenode> > > </tree> > > </attribute> > > </attributeList> > > </configuration-data> > > Then what's the problem? XPath works: > > s = <<END > <?xml version="1.0" encoding="UTF-8"?> > <configuration-data > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > xsi:schemaLocation="urn:company:platform:foundation:configuration:defn:v > 1" > xmlns="urn:company:platform:foundation:configuration:defn:v1"> > <attributeList> > <attribute name="siteid" validationRuleName="String" description="Site > id"> > <tree name="siteid_hierarchy"> > <treenode name="Root"> > <treenode name="1" /> > </treenode> > </tree> > </attribute> > </attributeList> > </configuration-data> > END > require 'rexml/document' > include REXML > doc = Document.new(s) > p XPath.match(doc, "//treenode['Root']/treenode") > #=> [<treenode name='1'/>] Wow. These results are just wrong. This is a bug in REXML. In XPath, when you do not specify a namespace for your node, that means that you want a node *with no namespace*. For example: require 'rexml/document' include REXML s = <<END <?xml version="1.0" encoding="UTF-8"?> <shop> <!-- car inventory --> <inventory xmlns="http://gm.com/"> <tire name="all season" /> </inventory> <!-- bike inventory --> <inventory xmlns="http://schwinn.com/"> <tire name="street" /> </inventory> <!-- no namespace inventory --> <inventory> <tire name="wtf" /> </inventory> </shop> END doc = Document.new(s) p XPath.match(doc, "//tire") REXML matches *all three* tires. Surely a car tire is not the same as a bike tire? Using XPath, how would I query for a tire that has *no namespace* (the third one) without matching the two that *do* belong in a namespace (it's possible to do this with REXML, just strange)? The XPath used above *should* only match the third entry. This is a broken implementation of XPath. > > Oh, wait, you said you were using libxml: > You have an error in your XML below > s = <<END > <?xml version="1.0" encoding="UTF-8"?> > <configuration-data> ^ That ">" should not be there. libxml-ruby has corrections turned on by default, so you've effectively removed all namespaces from this document. > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > xsi:schemaLocation="urn:company:platform:foundation:configuration:defn:v > 1" > xmlns="urn:company:platform:foundation:configuration:defn:v1"> > <attributeList> > <attribute name="siteid" validationRuleName="String" description="Site > id"> > <tree name="siteid_hierarchy"> > <treenode name="Root"> > <treenode name="1" /> > </treenode> > </tree> > </attribute> > </attributeList> > </configuration-data> > END > require 'rubygems' > require 'xml' > doc = XML::Document.string(s) > doc.find("//treenode['Root']/treenode").each do |el| > p el #=> <treenode name="1"/> > end > > Sorry, I'm failing to guess what problem you're having. Perhaps if you > showed your actual code? m. Since the namespaces were removed, this example succeeds. -- Aaron Patterson http://tenderlovemaking.com/