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/