xml-xmlbeans-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Waite <m...@akuma.org>
Subject Re: bug fix for XPath using Namespace
Date Fri, 18 Jun 2004 11:14:01 GMT
Namespace prefixes are determined by the context of the XPath 
expression, not that of the 'target' document.

I have a patch that uses XmlOptions (I think setSaveSuggestedPrefixes) 
to supply this information into XmlBeans for XPath usage. I'm fine with 
submitting this patch sometime this weekend - would a 'fresh' 
XmlOptions option be preferred over setSaveSuggestedPrefixes and the 
others present already?

-David Waite

On Jun 18, 2004, at 5:48 AM, nn wrote:

> Hi,
> I think it is important to remove the restriction for not allowing to 
> use
> namespace in complex XPath expression.
> (s.t ./po:purchaseOrder/po:shipTo[po:name = 'Helen Zoe']" ).
>
> Since otherwise, the useful XPath (which is provided by JAXEN) cannot 
> be
> used for most XML data associated with XMLSchema. I thought this may 
> be a
> restriction of JAXEN, but it wasn't.
> This fix is relatively simple. I  hope this should be incorporated in 
> the
> release (after reviewed by commiters and tested throughly).
>
> I'll attach the jar file.
>
> nn
>
> ------
>
> public class POTest {
>     public static void filter(XmlObject[] result) throws Throwable {
>         for (int i = 0; i < result.length; i++) {
>      XmlObject obj = result[i];
>      System.out.println(">> filter: "+obj.getClass()+", "+obj);
>  }
>     }
>     private static String[] test_xpathes = new String[]{
>   "//po:purchaseOrder",
>   "./po:purchaseOrder/po:shipTo/po:name",
>   "./po:purchaseOrder/po:shipTo[po:name = 'Helen Zoe']",
>   };
>
>     public static void test(PurchaseOrderDocument xmlObj, String xpath)
> throws Throwable {
>  System.out.println("\n===== test: xpath: "+xpath+" =====");
>  XmlObject[] result = xmlObj.selectPath(xpath);
>  filter(result);
>     }
>
>     public static void main(String argv[]) {
>  try {
>      File sourceID = new File(argv[0]);
>      PurchaseOrderDocument xmlObj =
> PurchaseOrderDocument.Factory.parse(sourceID);
>      for (int i = 0; i < test_xpathes.length; i++) {
>   test(xmlObj, test_xpathes[i]);
>      }
>  } catch (Throwable err) {
>      err.printStackTrace();
>  }
>     }
> }
> -----
> the result:
>
> ===== test: xpath: //po:purchaseOrder =====
>>> addNamespaces: prefix: po, uri: http://example.com/po
>>> filter: class com.example.po.impl.PurchaseOrderTypeImpl, 
>>> <xml-fragment
> xmlns:po="http://example.com/po">
>   <po:shipTo type="USAddress">
>     <po:name>Helen Zoe</po:name>
>     <po:street>47 Eden Street</po:street>
>     <po:city>Santa Clara</po:city>
>     <po:state>CA</po:state>
>     <po:zip>95054</po:zip>
>   </po:shipTo>
>   <po:billTo type="USAddress">
>     <po:name>Robert Zoe</po:name>
>     <po:street>47 Eden Street</po:street>
>     <po:city>Santa Clara</po:city>
>     <po:state>CA</po:state>
>     <po:zip>95054</po:zip>
>   </po:billTo>
>   <po:itemsList>
>     <po:item partNum="833-AA">
>       <po:productName>Lapis necklace</po:productName>
>       <po:quantity>1</po:quantity>
>       <po:USPrice>120</po:USPrice>
>       <po:comment>Want this for the holidays!</po:comment>
>       <po:shipDate>2001-12-15</po:shipDate>
>     </po:item>
>     <po:item partNum="423-AA">
>       <po:productName>Baby Sound Monitor</po:productName>
>       <po:quantity>2</po:quantity>
>       <po:USPrice>300</po:USPrice>
>       <po:comment>Got twins!</po:comment>
>       <po:shipDate>2001-12-17</po:shipDate>
>     </po:item>
>   </po:itemsList>
> </xml-fragment>
>
> ===== test: xpath: ./po:purchaseOrder/po:shipTo/po:name =====
>>> addNamespaces: prefix: po, uri: http://example.com/po
>>> filter: class org.apache.xmlbeans.impl.values.XmlStringImpl,
> <xml-fragment xmlns:po="http://example.com/po">Helen Zoe</xml-fragment>
>
> ===== test: xpath: ./po:purchaseOrder/po:shipTo[po:name = 'Helen Zoe'] 
> =====
>>> addNamespaces: prefix: po, uri: http://example.com/po
>>> filter: class com.example.po.impl.USAddressImpl, <xml-fragment
> type="USAddress" xmlns:po="http://example.com/po">
>   <po:name>Helen Zoe</po:name>
>   <po:street>47 Eden Street</po:street>
>   <po:city>Santa Clara</po:city>
>   <po:state>CA</po:state>
>   <po:zip>95054</po:zip>
> </xml-fragment>
>
> -----
> po.xml
>
> ?xml version="1.0"?>
> <po:purchaseOrder xmlns:po="http://example.com/po">
>    <po:shipTo type="USAddress">
>       <po:name>Helen Zoe</po:name>
>       <po:street>47 Eden Street</po:street>
>       <po:city>Santa Clara</po:city>
>       <po:state>CA</po:state>
>       <po:zip>95054</po:zip>
>    </po:shipTo>
>    <po:billTo type="USAddress">
>       <po:name>Robert Zoe</po:name>
>       <po:street>47 Eden Street</po:street>
>       <po:city>Santa Clara</po:city>
>       <po:state>CA</po:state>
>       <po:zip>95054</po:zip>
>    </po:billTo>
>    <po:itemsList>
>         <po:item partNum="833-AA">
>             <po:productName>Lapis necklace</po:productName>
>             <po:quantity>1</po:quantity>
>             <po:USPrice>120</po:USPrice>
>             <po:comment>Want this for the holidays!</po:comment>
>             <po:shipDate>2001-12-15</po:shipDate>
>         </po:item>
>         <po:item partNum="423-AA">
>             <po:productName>Baby Sound Monitor</po:productName>
>             <po:quantity>2</po:quantity>
>             <po:USPrice>300</po:USPrice>
>             <po:comment>Got twins!</po:comment>
>             <po:shipDate>2001-12-17</po:shipDate>
>         </po:item>
>     </po:itemsList>
> </po:purchaseOrder>
>
> ----
> po.xsd
> <xsd:schema targetNamespace="http://example.com/po"
>       xmlns="http://example.com/po"
>       xmlns:xsd="http://www.w3.org/2001/XMLSchema"
>       elementFormDefault="qualified"
>       attributeFormDefault="qualified">
>
>  <xsd:annotation>
>   <xsd:documentation xml:lang="en">
>    Purchase order schema for Example.com.
>    Copyright 2000 Example.com. All rights reserved.
>   </xsd:documentation>
>  </xsd:annotation>
>
>  <xsd:element name="purchaseOrder" type="PurchaseOrderType"/>
>
>  <xsd:element name="comment" type="xsd:string"/>
>
>  <xsd:complexType name="PurchaseOrderType">
>   <xsd:sequence>
>    <xsd:element name="shipTo" type="USAddress"/>
>    <xsd:element name="billTo" type="USAddress"/>
>    <xsd:element ref="comment" minOccurs="0"/>
>    <xsd:element name="itemsList"  type="Items"/>
>   </xsd:sequence>
>   <xsd:attribute name="orderDate" type="xsd:date"/>
>  </xsd:complexType>
>
>  <xsd:complexType name="USAddress">
>   <xsd:sequence>
>    <xsd:element name="name"   type="xsd:string"/>
>    <xsd:element name="street" type="xsd:string"/>
>    <xsd:element name="city"   type="xsd:string"/>
>    <xsd:element name="state"  type="xsd:string"/>
>    <xsd:element name="zip"    type="xsd:decimal"/>
>   </xsd:sequence>
>   <xsd:attribute name="country" type="xsd:NMTOKEN"
>      fixed="US"/>
>  </xsd:complexType>
>
>  <xsd:complexType name="Items">
>   <xsd:sequence>
>    <xsd:element name="item" minOccurs="0" maxOccurs="unbounded">
>     <xsd:complexType>
>      <xsd:sequence>
>       <xsd:element name="productName" type="xsd:string"/>
>       <xsd:element name="quantity">
>        <xsd:simpleType>
>         <xsd:restriction base="xsd:positiveInteger">
>          <xsd:maxExclusive value="100"/>
>         </xsd:restriction>
>        </xsd:simpleType>
>       </xsd:element>
>       <xsd:element name="USPrice"  type="xsd:decimal"/>
>       <xsd:element ref="comment"   minOccurs="0"/>
>       <xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
>      </xsd:sequence>
>      <xsd:attribute name="partNum" type="SKU" use="required"/>
>     </xsd:complexType>
>    </xsd:element>
>   </xsd:sequence>
>  </xsd:complexType>
>
>  <!-- Stock Keeping Unit, a code for identifying products -->
>  <xsd:simpleType name="SKU">
>   <xsd:restriction base="xsd:string">
>    <xsd:pattern value="\d{3}-[A-Z]{2}"/>
>   </xsd:restriction>
>  </xsd:simpleType>
>
> </xsd:schema>
>
> ---
> here is the code. I modified XBeansXPath.java and XBeansXPathAdv.java, 
> and
> added XBeansNamespace.java
>
> package org.apache.xmlbeans.impl.xpath.jaxen;
> ...
> public class XBeansXPath extends BaseXPath
> {
>     ....
>     public List selectNodes(Object node) throws JaxenException
>     {
>         XmlCursor xc;
>  XmlObject xmlObj;
>         if (node instanceof XmlObject)
>         {
>      xmlObj = (XmlObject)node;
>      xc = xmlObj.newCursor();
>         }
>         else if (node instanceof XmlCursor)
>  {
>      xc = (XmlCursor)node;
>      xmlObj = xc.getObject();
>             xc = xc.newCursor();
>         }
>         else
>             throw new IllegalArgumentException("node must be an 
> XmlObject or
> an XmlCursor, found: " + node.getClass());
>
>  XBeansNamespace.addNamespaces(this, xmlObj); // nn (support xpath 
> including
> namespace)
>         ((XBeansNavigator)getNavigator()).setCursor(xc);
>         return new ListImpl(super.selectNodes(
> XBeansNavigator.getBookmarkInThisPlace(xc) ));
>     }
> ....
> }
> ----
> package org.apache.xmlbeans.impl.xpath.jaxen;
> ...
> public class XBeansXPathAdv
>     extends BaseXPath
>     implements JaxenXBeansDelegate.SelectPathInterface
> {
> ...
>     public List selectNodes(Object node) throws JaxenException
>     {
>         XmlCursor xc;
>         xc = ((XmlCursor)node);
>  XmlObject xmlObj = xc.getObject();
>  XBeansNamespace.addNamespaces(this, xmlObj);
>         ((XBeansNavigator)getNavigator()).setCursor(xc);
>         return super.selectNodes(
> XBeansNavigator.getBookmarkInThisPlace(xc) );
>     }
> ...
> }
> -----
> package org.apache.xmlbeans.impl.xpath.jaxen;
> import org.jaxen.BaseXPath;
> import org.jaxen.JaxenException;
> import org.apache.xmlbeans.XmlObject;
> import org.apache.xmlbeans.XmlCursor;
>
> import java.util.List;
> import java.util.Map;
> import java.util.HashMap;
> import java.util.Iterator;
>
> public class XBeansNamespace
> {
>     public static void addNamespaces(BaseXPath baseXPath, XmlObject 
> doc)
> throws JaxenException {
>  HashMap nslist = getAdditionalNamespaces(getFirstChild(doc));
>  for (Iterator iter = nslist.entrySet().iterator(); iter.hasNext(); ) {
>      Map.Entry entry = (Map.Entry)iter.next();
>      String prefix = (String)entry.getKey();
>      String uri = (String)entry.getValue();
>      System.out.println(">> addNamespaces: prefix: "+prefix+", uri: 
> "+uri);
>      baseXPath.addNamespace(prefix, uri);
>  }
>     }
>     private static XmlObject getFirstChild(XmlObject xmlObj) {
>  XmlCursor xc = xmlObj.newCursor();
>  try {
>      xc.toFirstChild();
>      return xc.getObject();
>  } finally {
>      xc.dispose();
>  }
>     }
>     private static HashMap getAdditionalNamespaces(XmlObject xmlObj) {
>  HashMap nslist = new HashMap();
>  XmlCursor xc = xmlObj.newCursor();
>  try {
>      xc.getAllNamespaces(nslist);
>  } finally {
>      xc.dispose();
>  }
>  return nslist;
>     }
> }
>
>
>
> - ---------------------------------------------------------------------
> To unsubscribe, e-mail:   xmlbeans-dev-unsubscribe@xml.apache.org
> For additional commands, e-mail: xmlbeans-dev-help@xml.apache.org
> Apache XMLBeans Project -- URL: http://xml.apache.org/xmlbeans/
>


- ---------------------------------------------------------------------
To unsubscribe, e-mail:   xmlbeans-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xmlbeans-dev-help@xml.apache.org
Apache XMLBeans Project -- URL: http://xml.apache.org/xmlbeans/


Mime
View raw message