144 CHAPTER 4 XPATH, XPOINTER, XINCLUDE, AND THE FUTURE Comparisons I demonstrated simple comparisons earlier in this chapter, but that was before the introduction of functions. This section will provide a more in-depth look at expressions performing comparisons as well as calculations. I ll continue to use the document in Listing 4-6 as the document being queried. Performing a search based on a date may seem like a daunting task. Within the document, the element pubdate is using the format YYYY-MM-DD, which also conforms to the XML Schema date type. Unfortunately, XPath does not offer any date functions, so these values are treated as strings. However, string functions are available that can be manipulated to accomplish the task at hand. So, how do you go about selecting all books and magazines published in 2002? You will need substring functions to split the date apart. It is a given, because the dates conform to the XML Schema date type, that the first four characters are the year, so using the substring function, the starting position is 1 and the length is 4: /*/*[1]/*/*[*[local-name()=”pubdate” and substring(., 1, 4)=”2002″]] No, you are not going cross-eyed. This is really a valid XPath query. The initial path should look familiar to you. The path /*/*[1]/*/*is within the books subtree because you are using the first position, and it selects all element nodes on the level at which the bookelements reside. Within the document, this selects all bookelements, because no other types of elements are on this level within the bookssubtree. The predicate is where you may get a little bug-eyed. Breaking the predicate, [*[local-name()=”pubdate” and substring(., 1, 4)=”2002″]], into pieces, the first * indicates that the filter takes place on all child elements of the current node set. The current node set, in this case, consists of all the book elements. That leaves another predicate: [local-name()=”pubdate” and substring(., 1, 4)=”2002″]. This predicate is performed on all the child elements of the current node set. The first test is to see whether the local name matches pubdate. If this returns TRUE, then you know the current node being run against this filter is a pubdate element. You can then check the string value of this element using the substring function to see whether the first four characters match 2002. The reason the first parameter is . (a period) is that the context node itself or the current node is being passed as an argument to the function. You can also write the substringfunction as substring(self::*, 1, 4) or substring(child::text(), 1, 4). An element has a string value that consists of all text nodes within its contents and the contents of its children. Passing in the context node, which must be a pubdate element since it passed the first check, will effectively pass in the text containing the date being searched. This query may have looked complicated but, once broken out, should be easy to understand. Well, you have selected all the book elements, but the query is supposed to also return all the magazine elements published in 2002. You face a few problems: the elements do not live on the same level within the document, the names of the elements being returned are not the same, the element names containing the dates are not the same, and they also live in different subtrees. For starters, the magazine elements that have an issue date in 2002 will be selected: /*/*[2]/*[*[local-name()=”issue” and substring(., 1, 4)=”2002″]] This query is almost the same as the query for the book elements. The differences here are that the magazine subtree is being traversed (indicated by the /*/*[2]portion of the path), the steps are not as deep (notice there is a /* removed from the path), and the local name test is now performed against the string issue. The query is broken down the same way the previous book selection was broken down.
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost PHP Web Hosting services