Hi folks!

I recently started learning some PHP/XML stuff and I have had a fair bit of success with it so far.

However, I am currently trying to do something I haven't tried before, which is parsing an XML file with the variables in PHP to be one node attribute conditionally selected by the value of related node attributes.

For instance...

<ROOT>
<BOOKS>
<BOOK TYPE="10" CAT="SCIENCE" TITLE="RANDOMTITLE">
<BOOK TYPE="10" CAT="ART" TITLE="RANDOMTITLE2">
<BOOK TYPE="10" CAT="NATURE" TITLE="RANDOMTITLE3">
</BOOKS>
</ROOT>

What I want to be able to do is to iterate through each BOOKS and only parse the TITLE element if TYPE is equal to "10"and CAT equal to "ART". Obviously, the sample above is a smaller version of the XML tree and is just here for demonstration purposes only.

I am pretty much fine with the concept of iterating with foreach statements using xpath to set variable from $book1 = $BOOKS-BOOK[0] etc. I have managed to successfully parse XML documents like this no problem. However, I just can't seem to be able to figure out how to return one node as the variable based on the value of related nodes. I've tried books, loads of google searches etc but I just can't seem to get a handle on how to do this.

Any help with this would be most appreciated!

Thanks in advance,

NDF.

    That's the sort of thing XPath was designed for...

    //BOOK[@TYPE='10'][@CAT='SCIENCE']/@TITLE

      Thank you very much for your response!

      <ROOT>
      <BOOKS>
      <BOOK>
      <DETAILS TYPE="10" CAT="SCIENCE" TITLE="RANDOMTITLE">
      <DETAILS TYPE="10" CAT="ART" TITLE="RANDOMTITLE2">
      <DETAILS TYPE="10" CAT="NATURE" TITLE="RANDOMTITLE3">
      </BOOK>
      </BOOKS>
      </ROOT>

      On reflection, the above might be a more accurate exacmple of what I am trying to do. The tree has multiple BOOK children on it. I need to iterate through each one and, as mentioned before, return the TITLE based on the criteria matching with certain values in the related nodes.

      I am a little confused as to how I structure the PHP code to do this.


      $BOOKCAT = simplexml_load_file('BOOKS.xml');

      foreach ($BOOKCAT->BOOKS->xpath('//BOOK') as $BOOK) {

      $bookarray = array( $booktitle = XXXXXXXXXXXXXXXXXXX
      )}

      And that is where I am struck. I don't know how to get it to iterate each DETAILS for the selected criteria and get it to create the variable based on it if it gets a match.

      Thanks again. I feel like a total amateur here BTW...

        Well, the XPath I gave would find the TITLE attribute of all of the BOOK elements with the given CAT and TYPE. You could simply iterate over what it returns (i.e., substitute that XPath for your original). The XPath string itself is of course an ordinary string, so you can use PHP variables inside it as normal (note of course you'd be wanting to use a double-quoted string so that PHP will parse it for variables: [font=monospace]"//BOOK[@TYPE='$type'][@='$cat']/@TITLE"[/font]).

        If on the other hand you already have a node and start your search at it (like a relative path sort of thing), you can specify it as the context as $BOOK->xpath("...").

        If you're wanting all of the attributes for a given node - their names as well as their values - a SimpleXMLElement like $BOOK has a method attributes() that you can iterate over:

        foreach($BOOK->attributes() as $name=>$value) {}

        What you then do with the strings $name and $value is up to you, of course; what I'd be likely to do would be to make an associative array $attributes[$name]=$value, because I like the array functions.

        Caveat: I write all the above without having that much experience working with SimpleXML. I learned [man]DOM[/man] first, and have stayed with it - in large part because it's more widely implemented.

          19 days later

          Hello again.

          I've not been on this thread as I have been trying for a while to try and resolve this using the information given and some more reseach, but I just can't seem to get it done. My working knowledge of PHP is limited, but I have had success parsing simpler XML streams in the past.

          Back to the original question...

          Out of respect to the people helping me, I have put together an example which I hope will be clearer.

          This is the basic structure of the XML (with dashes so it displays better here and is easier to read): -

          <LIBRARY>
          ------<CATALOGUE>
          ------------<BOOK TITLE="NEW ITALIAN CUISINE">
          ------------------<CHAPTER ID="4" NAME="MAIN COURSES" PAGECOUNT="65">
          ------------------<CHAPTER ID="2" NAME="GETTING STARTED" PAGECOUNT="14">
          ------------------<CHAPTER ID="1" NAME="INTRODUCTION" PAGECOUNT="23">
          ------------------<CHAPTER ID="3" NAME="SIMPLE STARTERS" PAGECOUNT="56">
          ------------</BOOK>
          ------------<BOOK TITLE="NEW GREEK CUISINE">
          ------------------<CHAPTER ID="1" NAME="INTRODUCTION" PAGECOUNT="56">
          ------------------<CHAPTER ID="3" NAME="SIMPLE STARTERS" PAGECOUNT="59">
          ------------------<CHAPTER ID="4" NAME="MAIN COURSES" PAGECOUNT="12">
          ------------------<CHAPTER ID="2" NAME="GETTING STARTED" PAGECOUNT="18">
          ------------</BOOK>
          ------------<BOOK TITLE="NEW FRENCH CUISINE">
          ------------------<CHAPTER ID="2" NAME="GETTING STARTED" PAGECOUNT="23">
          ------------------<CHAPTER ID="3" NAME="SIMPLE STARTERS" PAGECOUNT="56">
          ------------------<CHAPTER ID="4" NAME="MAIN COURSES" PAGECOUNT="64">
          ------------------<CHAPTER ID="1" NAME="INTRODUCTION" PAGECOUNT="17">
          ------------</BOOK>
          ------</CATALOGUE>
          </LIBRARY>

          What I am looking to do is create a script that will return the name of the book, and also the number of pages in each chapter, given that each chapter the criteria of:

          ID="1", NAME="INTRODUCTION"
          ID="2", NAME="GETTING STARTED"
          ID="3", NAME="SIMPLE STARTERS"
          ID="4", NAME="MAIN COURSES"

          ... as all of them do in the above example. However, I can't simply use CHAPTER[0], CHAPTER[1] etc as the chapter numbers are not in order. I am basically just using this as an example of how I can navigate and parse XML based on the attributes.

          The aim will be to send it to a MySQL database. The code for that, I have done OK. It's the creation of the array based on the criteria above I having trouble understanding.

          So far, I just have this basic outline: -

          <?php
          
          $Library =  simplexml_load_file('catalogue.xml');
          
          foreach ($Library->CATALOGUE->xpath('//BOOK') as $Book) {
          
          $bookarray = 		array 		(
                                                                  $Booktitle = $Book['TITLE'],
          							$Chapter1pagecount = ???????????????,
          							$Chapter2pagecount = ???????????????,
          							$Chapter3pagecount = ???????????????,
          							$Chapter4pagecount = ???????????????);
          }
          
          ?>

          I am just simply stuck at how to get those attributes to parse OK.

          Anyway... sorry to bother you all again... but this is ssssooooo frustrating!!!

            Can anyone help please?

              8 days later

              Think I finally worked it out. Thanks to all those that helped me!

                I know have a further problem with this. I have the code working OK... but the problem is the syntax above produces an array with the foreach array for parsing. Apparently, PHP don't like this. I have tried flushing the array at the end of each loop, but this doesn't seem to work.

                Anybody know if there is a workaround for this?

                  Write a Reply...