XPath get attribute value in PHP
XPath can do the job of getting the value attribute with $xpath->query("//input[@name='text1']/@value");
. Then you can iterate over the node list of attribute nodes and access the $value
property of each attribute node.
Get attribute values SimpleXML Xpath PHP
Not sure what you really try to do. As far as I understand...
$xml = simplexml_load_string($x); // assuming XML in $x
$hit = (string)$xml->xpath("/RESULTS/ROW[COLUMN/@NAME='ID' and COLUMN/text() = '001']/COLUMN[@NAME='NAME']")[0];
Above code step by step:(string)
will force the result to string, instead of object- xpath-expression: get
<ROW>
with a child<COLUMN>
with an attributeNAME='ID'
and a value of001
- starting from that specific
<ROW>
, select a child<COLUMN>
with an attribute ofNAME='NAME'
xpath()
returns an array ofSimpleXml
elements, by[0]
we select its first entry.- be aware that this code lacks checking if there's a match at all.
EDIT:
Re-read the question. To get the result you want, select the <ROW>
and then iterate over the <COLUMN>
:
$hit = $xml->xpath("/RESULTS/ROW[COLUMN/@NAME='ID' and COLUMN/text() = '001']")[0];
foreach ($hit as $column)
echo $column['NAME'] . ": " . $column . PHP_EOL;
Output: ID: 001
NAME: ORG001
CODE: 1234
see https://eval.in/503493 Xpath query in PHP to attribute from element with specific attribute value
As it turns out from the chat conversation from my original question I had to register the namespace. In the end I used this website and the code turned out to be like this:
$feed = new DOMDocument();
$feed->load("http://www.wildstarfans.net/feeds/posts/default");
$xpath = new DOMXPath($feed);
$xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
foreach ($xpath->evaluate('//atom:entry') as $entry) {
$href = $xpath->evaluate('string(atom:link[@rel="alternate"]/@href)', $entry);
}
Credits go to ThW and Wrikken. Wish I could give you guys SO points for this. PHP XPath to get a part of an attribute value
As mentioned here and here, you unfortunately can't accomplish this in one query with XPath 1.0.
What you could do instead is list all the title
attributes belonging to these <td>
s, then use preg_match
to grab anything that's after an =
surrounded by spaces:
$rowTitleAttrs = $xmlSite->xpath('//tr[@class="showif_out"]/td/@title');
$phoneNumbers = [];
foreach ($rowTitleAttrs as $rowTitleAttr) {
if (preg_match('/(?<= = )(?<phoneNumber>.*?)$/', $rowTitleAttr->title, $matches)) {
$phoneNumbers[] = $matches['phoneNumber'];
}
}
I took the liberty of simplifying your XPath query in the process, as a class name should be accurate enough to not have to state the whole path leading to it.Demo: https://3v4l.org/1oqqA
Getting Text Value of Data-Attribute Link in DOM XPath
Quite often I find it easiest to "inspect" the element I wish to target using the developer tools in Chrome from where it is possible to copy the XPath expression that targets that particular node. This doesn't always return the most useful XPath expression but it is usually a good starting point - in this case I tweaked the returned query and added in the classname.
Hope it helps
$term='dog show';
$url=sprintf('https://en.wikipedia.org/w/index.php?search=%s&title=Special:Search&fulltext=Search', urlencode( $term ) );
printf( '<a href="%s" target="_blank">%s</a>', $url, $url );
libxml_use_internal_errors(true);
$dom=new DOMDocument;
$dom->recover=true;
$dom->formatOutput=true;
$dom->preserveWhiteSpace=true;
$dom->strictErrorChecking=false;
$dom->loadHTMLFile( $url );
$xp=new DOMXPath( $dom );
/* possibly the important bit */
$query='//*[@id="mw-content-text"]/div/ul/li/div[@class="mw-search-result-heading"]/a';
$col=$xp->query( $query );
$html=array();
if( $col && $col->length > 0 ){
foreach( $col as $node ){
$html[]=array(
'title'=>$node->nodeValue,
'href'=>$node->getAttribute('href')
);
}
}
printf('<pre>%s</pre>',print_r($html,true));
Will output:https://en.wikipedia.org/w/index.php?search=dog+show&title=Special:Search&fulltext=Search
Array(
[0] => Array
(
[title] => Dog show
[href] => /wiki/Dog_show
)
[1] => Array
(
[title] => Show dog
[href] => /wiki/Show_dog
)
[2] => Array
(
[title] => Westminster Kennel Club Dog Show
[href] => /wiki/Westminster_Kennel_Club_Dog_Show
)
[3] => Array
(
[title] => Dog Eat Dog (U.S. game show)
[href] => /wiki/Dog_Eat_Dog_(U.S._game_show)
)
.......... etc
XPATH Get Attribute of Current Node
You can achieve this by using getAttribute()
method. Example:
foreach($nodeLIST as $node) {
$attribute = $node->getAttribute('class');
if($attribute == 'title') {
// do something
} elseif ($attribute == 'child') {
// do something
}
}
XPath to locate element based on attribute value?
As Micheal Kay has outlined in his answer, the xpath expression is valid. What he does not know is that for SimpleXML this won't lead into an empty result.
So you see a fatal error as you try to read a field from an empty array. Your code works similar to this one:
$found = array();
echo $found->state;
Which echoes an empty string (created out of the NULL
value that expression give) and a notice:If you don't see yet this notice, it's crucial you enable error messages with your development system, see How to get useful error messages in PHP?.Notice: Trying to get property of non-object in ...
So as you can see, it is working properly, it just does not provide what you expect. To go on with that in a more productive manner for yourself, it would have been great if you would have shared what exactly you did expect instead.
Or in other words: As others have answered as well, you need to decide what you're looking for.
From the output code:
echo $found->state;
I'd say you're looking for the following XML element:...
<repstate location="AK">
<compName>Test Company</compName>
<name>Chris Brown</name>
<address>123 Main St</address>
<city>Anytown</city>
<state>CT</state>
...
So here is how SimpleXML Xpath works:- you can only query lists of nodes
- the only nodes supported are elements and attributes
- the list is always of type array
- the array is always zero-indexed
- each entry in the array - if the array is not empty - is of type SimpleXMLElement
$list = $xml->xpath("//repstate[@location = 'AK']");
list($repstate) = $list + array(null);
$state = $repstate ? $repstate->state : '- no such location -';
echo $state;
The output with your XML then would be:Or even shorter:CT
$list = $xml->xpath("//repstate[@location = 'AK']/state");
list($state) = $list + array('- no such location -');
echo $state;
I hope this more expansive explanation is helpful for you. The reason why your original expression does not work is that it's already violating the first point:- you can only query lists of nodes
How can I get all attributes with PHP xpath?
In XPath, you can use @*
to reference attributes of any name, for example :
$nodes = $xpath->query('//div/@*');
foreach ($nodes as $node) {
echo $node->nodeName ." : ". $node->nodeValue ."<br>";
}
eval.in demo
output :
class : example-class
data-caption : Example caption
data-link : https://www.example.com
data-image-url : https://example.com/example.jpg
PHP/SimpleXML/XPath get attribute value by another attribute in same element
I think you problem might be the namespace. PPTX Relationship files use the namespace "http://schemas.microsoft.com/package/2005/06/relationships". But SimpleXmls xpath does it's own magic, too. If the file contains the namespace (check the source) you have to register an own prefix for it.
$xml = <<<'XML'
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<Relationships
xmlns="http://schemas.microsoft.com/package/2005/06/relationships">
<Relationship Id="rId1"
Type="http://schemas.microsoft.com/office/2006/relationships/image"
Target="http://en.wikipedia.org/images/wiki-en.png"
TargetMode="External" />
<Relationship Id="rId2"
Type="http://schemas.microsoft.com/office/2006/relationships/hyperlink"
Target="http://www.wikipedia.org"
TargetMode="External" />
</Relationships>
XML;
$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);
$xpath->registerNamespace('r', 'http://schemas.microsoft.com/package/2005/06/relationships');
var_dump(
$xpath->evaluate("string(/r:Relationships/r:Relationship[@Id='rId2']/@Target)", NULL, FALSE)
);
Output:string(24) "http://www.wikipedia.org"
Xpath does not know something like a default namespace. Without a prefix you look for elements without any namespace. Attributes don't have a namespace if not explicitly prefixed.To make the confusion complete, do the PHP functions (SimpleXMLElement::xpath(), DOMXpath::query() and DOMXpath::evaluate()) automatically register the namespace definitions of the used context. The third argument allows to disable that behaviour.
Unlike the other two functions, DOMXpath::evaluate() can return scalars directly.
Related Topics
PHP Require File from Top Directory
Number in the Top-Level Domain
Doctrine2 - "Class" Is Not a Valid Entity or Mapped Super Class
Codeigniter 4 Problem Installing with Composer
PHP Pdo Bindparam Was Falling in a Foreach
Dynamic Class Property $$Value in PHP
Why Should I Never Run 'Composer Update' in Production
How to Convert Latin1_Swedish_Ci Data into Utf8_General_Ci
Laravel 5 Auth Post Submit - Tokenmismatchexception in Verifycsrftoken.PHP Line 46
PHP Prepared Statements and Transactions in a Loop
How to Find "Related Items" in PHP
Get Calling File Name from Include()
Notice: Ob_End_Flush(): Failed to Send Buffer of Zlib Output Compression (1) In
Yii Framework 2.0 Login with User Database
Order Properties Should Not Be Accessed Directly - Woocommerce 3.0