XPath incorrect query path [duplicate] - php

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Xpath fails if an element has a a xmlns attribute
I have been trying for a long time to extract a string from the following xml with no luck
http://chris.photobooks.com/xml/default.htm?state=8T
I am trying to get the ASIN number of a book and I have tried
$xpath->query('//MarketplaceASIN/ASIN')->item(0)->nodeValue;
and
$xpath->query('/GetMatchingProductResponse/GetMatchingProductResult[1]/Product/Identifiers/MarketplaceASIN/ASIN')->item(0)->nodeValue;
but neither seem to work, what am I doing wrong here?

The elements in that document are bound to the namespace http://mws.amazonservices.com/schema/Products/2011-10-01.
You may have missed it because it does not use a namespace-prefix and the xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01" just looks like an attribute, but namespace attributes are special.
All of the descendant elements inherit that namespace. You will want to register the namespace with a namespace-prefix and adjust your XPath:
$rootNamespace = $xml->lookupNamespaceUri($xml->namespaceURI);
$xpath->registerNamespace('a', $rootNamespace);
$elementList = $xpath->query('//a:MarketplaceASIN/a:ASIN');
Or you could use a more generic XPath that matches on elements and uses a predicate filter to match the local-name() and namespace-uri():
//*[local-name()='MarketplaceASIN' and namespace-uri()='http://mws.amazonservices.com/schema/Products/2011-10-01']/*[local-name()='ASIN' and namespace-uri()='http://mws.amazonservices.com/schema/Products/2011-10-01']

Related

PHP Trying to Get Simple XML Attribute Value [duplicate]

This question already has answers here:
Reference - How do I handle Namespaces (Tags and Attributes with a Colon in their Name) in SimpleXML?
(2 answers)
Closed 4 years ago.
Here is my XML:
<WebContent diffgr:id="WebContent1" msdata:rowOrder="0">
<orig_inv_no>73</orig_inv_no>
<inv_no>141</inv_no>
<inv_type>S</inv_type>
<content_type>3</content_type>
<content_type_desc>Test</content_type_desc>
<content_value>Sample content</content_value>
</WebContent>
<WebContent diffgr:id="WebContent2" msdata:rowOrder="0">
<orig_inv_no>73</orig_inv_no>
<inv_no>141</inv_no>
<inv_type>S</inv_type>
<content_type>3</content_type>
<content_type_desc>Test</content_type_desc>
<content_value>Sample content</content_value>
</WebContent>
I am having a lot of trouble getting the attribute "differ:id" for the node "WebContent"
It seems like it doesn't like the colon in the attribute name. Any Ideas?
the attribute is "diffgr:id" not "differ:id" maybe this is your issue
Try this:
$xml->WebContent->attributes("diffgr",TRUE)->id;
// TRUE means that `diffgr` is a prefix of the attribute
COuld be found here -> https://stackoverflow.com/a/15546669/2040840

Simple XML read element namespace attribute [duplicate]

This question already has answers here:
Reference - How do I handle Namespaces (Tags and Attributes with a Colon in their Name) in SimpleXML?
(2 answers)
Closed 4 years ago.
I have an XML, schema below
$xml =
'<NodeSet
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">
<Node category="category" i:type="ObjectNode">
<NodeId>
<Identifier>i=86</Identifier>
</NodeId>
</Node>
</NodeSet>';
I need to extract the i:type attribute value from the Node element. I have tried accessing it as i would do it when accessing normal attributes but it seems it doesn't work that way
Here is how i can access the category attribute,
$xml=simplexml_load_string($xml);
echo $xml->Node[0]['category']; //this prints 'category' as expected
echo $xml->Node[0]['i:type']; //prints nothing, how do i get the i:type attribute value ?
You need to access the attributes with the namespace, this can be done using the attributes() method...
echo $xml->Node[0]->attributes("i",true)['type'];
Using ("i",true) says use the i prefix rather than having to put the URI.

Get an attribute value using SimpleXML for PHP [duplicate]

This question already has answers here:
Accessing #attribute from SimpleXML
(10 answers)
Closed 6 years ago.
I use SimpleXMLElement class for working with xml files in my project.
My question is: how to get an attribute value of some tag with some attribute? You may assume I know the name of the tag, the name of the attribute and it's location inside the xml file. For example, for such a string <someTag cp="c2"> knowing values 'someTag' and 'cp' I want to obtain the string "c2".
Thanks is advance.
You can use the attributes() function on the node to get it's attributes:
$xml_str = '<xml>
<node>
<someTag cp="c2">content</someTag>
</node>
</xml>';
$res = simplexml_load_string($xml_str);
$items = $res->xpath("//someTag");
var_dump((string) $items[0]->attributes()->cp);
The returned element is an SimpleXMLElement, so in order to use it I converted it to string (using the (string) cast).

How to get XML nodes content when names include special Characters? [duplicate]

This question already has answers here:
Simple XML - Dealing With Colons In Nodes
(4 answers)
Closed 9 years ago.
Im trying to navigate an XML block similar to this one ($doc) using PHP simplexml_load_string and using xpath on $doc to get only the 'Day' block like this:
$myday = $doc->xpath ('//Day');
that lets me access all data from the block as an object, meaning
$myday->AdultCount;
returns 1 and
$myday->Id;
returns "6a0"
however I can't access "SpecialDeals" content not using:
$myday->SpecialDeals
nor using:
$myday->SpecialDeals->a:string
Whats is the right syntax in this case?
<Days>
<DaysId>687</DaysId>
<Day>
<AdultsCount>1</AdultsCount>
<Availability>Available</Availability>
<Id>6a0</Id>
<RoomType>Studio</RoomType>
<SpecialDeals xmlns:a="http://microsoft.com/2003/Arrays">
<a:string>Best Day Ever</a:string>
</SpecialDeals>
</Day>
<DaysPrice>247.4</DaysPrice>
</Days>");
You can access the tags with colons in them (aka namespaces) using the children() method:
echo $xml->Day->SpecialDeals->children('a', true)->string[0];
Demo!
This SitePoint article explains namespaces in detail.

Remove empty XML elements with phpQuery [duplicate]

This question already has answers here:
Reg expression to remove empty Tags (any of them)?
(3 answers)
Closed 9 years ago.
As mentioned in title, I'd like remove all empty elements from XML document.
By empty I mean elements that don't have any text nodes in it or in its children.
Is it possible to do that with phpQuery?
I used Gordon's code from answer in this topic: Reg expression to remove empty Tags (any of them)?
Firstly I tried just to put his XPath query into phpQueryObject::find() method, but it gave me a warning saying it's incorrect query. Don't know why since it's using DOMXPath and should work.
Anyway the solution was still quite simple.
$pqDoc = phpquery::newDocument() // phpQueryObject created some way. Doesn't matter here.
$xp = new DOMXPath($pqDoc->getDOMDocument());
foreach($xp->query('//*[not(node()) or normalize-space() = ""]') as $node) {
$node->parentNode->removeChild($node);
}
Now you have removed empty elements and you still can use your changed phpQueryObject since it has actually working on DOMDocument's reference.

Categories