simplexml xpath add tag
David (imported from SE)
I have a PHP xpath query that works well for searching on a single node of my XML file. In simplified form, it looks like this:

    $url = 'myfile.xml';
    $xml = simplexml_load_file($url);
    $xml->registerXPathNamespace("h", "https://library.example.ac.uk");
    
    $found = $xml->xpath("//h:row[h:AUTHOR1[contains(.,'$search')]]");
    ...

The limitation is that it only finds AUTHOR1, but this XML library catalog file can contain multiple authors, like this sample entry:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<table xmlns="https://library.example.ac.uk">
  <row>
    <AUTHOR1>FABER, Adele</AUTHOR1>
    <AUTHOR2>MAZLISH, Elaine</AUTHOR2>
    <AUTHOR3></AUTHOR3>
    <AUTHOR4></AUTHOR4>
    <CALLNO>306.875 FAB</CALLNO>
    <COPIES>1</COPIES>
    <COPYNO>1.</COPYNO>
    <CUSTOM1>2011</CUSTOM1>
    <CUSTOM2></CUSTOM2>
    <EDITION></EDITION>
    <IBARCODE>856490.</IBARCODE>
    <ISBN>0380705273</ISBN>
    <PLACEPUBL>New York</PLACEPUBL>
    <PUBLISHER>Norton</PUBLISHER>
    <SUBJECT1>Child rearing</SUBJECT1>
    <SUBJECT2>Sibling rivalry</SUBJECT2>
    <SUBJECT3>Psychology</SUBJECT3>
    <SUBJECT4></SUBJECT4>
    <SUBJECT5></SUBJECT5>
    <TITLE>Siblings without rivalry : how to help your children live together so you can live too</TITLE>
    <WEBSITE/>
    <WORDCOUNT>0</WORDCOUNT>
  </row>
</table>
```

My current search will only find "FABER", but I would like it also to be able to find "MAZLISH".

I thought this would be a job for `starts-with`, but no syntax I have tried will work. I thought I could do something like:

    $xml->xpath("//h:row[h:[starts-with(name(), 'AUTHOR')[contains(...

But I cannot get any variant of that to work. (The problem is not the nesting of quotes or brackets, I'm quite sure.) And I have tried both `name` and `local-name` for the `starts-with` bit.

So! How to find hits on any of the `AUTHOR1`, `AUTHOR2`, `AUTHORn`... nodes?
Top Answer
Nigel Ren (imported from SE)
The problem is more with how you select the nodes, `name()` will give you the name including the prefix, so you don't need to specify this as a separate part of the query (I think as it's the default prefix it is blank).  So the value will be `AUTHOR1` etc.  So change the way that you select the author nodes to just use `/*[starts-with(name(), 'AUTHOR')]`...

    $found = $xml->xpath("//h:row[*[starts-with(name(), 'AUTHOR')][contains(.,'$search')]]");
    
You can always add `/..` to the end of the XPath to backtrack to the row element:  
`//h:row/*[starts-with(name(), 'AUTHOR')][contains(.,'$search')]/..`

This room is for discussion about this question.

Once logged in you can direct comments to any contributor here.

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.