In case anybody has a tip, I'm all ears. I have an issue with getting jquery to run xpath expressions (on FF) when the equavalent CSS expression works fine. I have posted to jquery's lists, but haven't received a good answer yet. Any ideas? Here's the problem:
1. Perform an ajax request using Prototype's Ajax.request, with an
onComplete callback to my function. Here's a sample response:
2. In my function, calling jQuery("//ProductType/Properties/
PropertyTemplate") on the responseXML property of the response. I
get zero elements.
3. Replacing the jquery with a css-style selector, works: jQuery
("ProductType Properties PropertyTemplate") returns 1 element.
This is a simple case. I have more complex ones that require Xpath, so the css equivalent isn't an option. Thanks for the help!
-jeff
1. Perform an ajax request using Prototype's Ajax.request, with an
onComplete callback to my function. Here's a sample response:
<?xml version="1.0"?> <XMLResponse> <Errors/> <Warnings/> <Messages/> <Response> <ProductType> <Id>40</Id> <Name>Chain</Name> <ProductGroup>BMX</ProductGroup> <Margin/> <Properties> <PropertyTemplate> <Sid>44c0ade1561d3</Sid> <ProductTypeId>40</ProductTypeId> <PropertyTypeId>34</PropertyTypeId> <PropertyType/> <Required>0</Required> <Name>Weight</Name> <Type>1</Type> </PropertyTemplate> </Properties> </ProductType> </Response> </XMLResponse>
2. In my function, calling jQuery("//ProductType/Properties/
PropertyTemplate") on the responseXML property of the response. I
get zero elements.
3. Replacing the jquery with a css-style selector, works: jQuery
("ProductType Properties PropertyTemplate") returns 1 element.
This is a simple case. I have more complex ones that require Xpath, so the css equivalent isn't an option. Thanks for the help!
-jeff
#
2
03-08-2007, 06:25 PM
|
If you have Ext, did you try DomQuery? It should work fine with either query and will be slightly faster anyway.
|
#
3
03-08-2007, 08:15 PM
|
I thought that DomQuery was now leveraging/wrapping JQuery?
Anyway, my test shows that node-list predicate selectors aren't working in DomQuery either. These are the cases where I need Xpath over css. Take this example: XML Document: <XMLResponse> <Errors/> <Warnings/> <Messages/> <Response> <NinestarStyle> <Sid>S44c14b83172b03.48738167</Sid> <Name>Another Original Cap</Name> <Properties/> <ProductTypeId>5</ProductTypeId> <VendorItemId>35011077Y</VendorItemId> <VendorId>DWIND</VendorId> <BrandId>DWIND</BrandId> <Price>19.99</Price> <Margin/> <DefaultCost/> <Taxable>1</Taxable> <Persisted>1</Persisted> <Instock/> <ItemPropertyGroups/> <ProductType> <Id>5</Id> <Name>Hats</Name> <ProductGroup>Fashion</ProductGroup> <Margin/> <Properties> <PropertyTemplate> <Sid>44c0ade005d75</Sid> <ProductTypeId>5</ProductTypeId> <PropertyTypeId>8</PropertyTypeId> <PropertyType> <Id>8</Id> <Name>Hats Size</Name> <DataType>1</DataType> <Units/> <VendorSpecific>0</VendorSpecific> </PropertyType> <Required>1</Required> <Name>Size</Name> <Type>0</Type> </PropertyTemplate> <PropertyTemplate> <Sid>44c0ade0078cc</Sid> <ProductTypeId>5</ProductTypeId> <PropertyTypeId>2</PropertyTypeId> <PropertyType> <Id>2</Id> <Name>Color</Name> <DataType>1</DataType> <Units/> <VendorSpecific>1</VendorSpecific> </PropertyType> <Required>0</Required> <Name>Color</Name> <Type>0</Type> </PropertyTemplate> </Properties> </ProductType> <_propertiesLoaded>1</_propertiesLoaded> <_categoriesLoaded>1</_categoriesLoaded> <_deep>1</_deep> </NinestarStyle> </Response> </XMLResponse> //NinestarStyle/ProductType/Properties/PropertyTemplate This selector, however, returns no nodes: //NinestarStyle/ProductType/Properties/PropertyTemplate[Type='0'] |
#
4
03-08-2007, 10:53 PM
|
jQuery will be offering an option to use DomQuery as it is faster (but also larger).
//NinestarStyle/ProductType/Properties/PropertyTemplate[Type='0'] This is where CSS selectors take precedence over XPath. In CSS selectors that is an attribute query, not a "nodeValue" query. Adding it is easy though, and I have a added a pseudo to DomQuery ("nodeValue") that will in the next release. In the mean time, you can add this code anywhere after Ext and it will be available now: Ext.DomQuery.pseudos.nodeValue = function(c, v){ var r = []; for(var i = 0, ci; ci = c[i]; i++){ if(ci.firstChild && ci.firstChild.nodeValue == v){ r[r.length] = ci; } } return r; } Your query would be: //NinestarStyle/ProductType/Properties/PropertyTemplate:nodeValue(0) |
#
5
03-08-2007, 11:28 PM
| |
Quote:
//NinestarStyle/ProductType/Properties/PropertyTemplate/Type:nodeValue(0)/../ Since support for these should be easy (it's just a recursion), how about a DomQuery mode switch CSS or XPath type predicates? The only change would be if an @ is required to signify an attribute. |
#
6
03-08-2007, 11:47 PM
|
Yes it would have Type.
The switch you suggested requires some changes to the parser and internal logic. I'm not sure how difficult they would be but it won't be changed in this release. That code is stable and there are other things which need to get finished. |
#
7
03-08-2007, 11:51 PM
|
Thanks for the help Jack. I think I'll be able to develop a suitable workaround.
|
#
8
03-12-2007, 09:01 PM
| |
Quote:
Still having problems... what would the correct syntax be? For example, if I want to retrieve the _value node for the property with Sid 44c0e4bee03cf from the XML snipppet below: <Properties> <Property> <Sid>44c0e4bee03cf</Sid> <ValueSid>44c0e4bee03cf</ValueSid> <VendorId>DWIND</VendorId> <_value>YOUTH</_value> ... Properties/Property[Sid:nodeValue("+sid+")]/_value Properties/Property/Sid:nodeValue("+sid+") Properties/Property/Sid:nodeValue("+sid+")/../_value Properties/Property/Sid:nodeValue("+sid+"):parent()/_value Ext.DomQuery.pseudos.parent = function(c){ var r = []; for(var i = 0, ci; ci = c[i]; i++) if(ci.parentNode) r[r.length] = ci.parentNode; return r; } |
#
9
03-12-2007, 09:09 PM
| |
Quote:
|
#
10
03-12-2007, 09:14 PM
|
Jack,
I wrote a custom pseudo selector to do exactly what I want, but it's a disappointing hack. This functionality should be part of the Xpath library. Ext.DomQuery.pseudos.nodeValueParent = function(c, v){ var r = []; for(var i = 0, ci; ci = c[i]; i++){ if(ci.firstChild && ci.firstChild.nodeValue == v){ r[r.length] = ci.parentNode; } } return r; } |