Pro PHP XML and Web Services phần 5 pptx

94 354 0
Pro PHP XML and Web Services phần 5 pptx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

defines the expression to test using the test attribute. This is the same as the test attribute on the xsl:if element. When it evaluates to TRUE, the content of the element is instantiated; otherwise, the next xsl:when element is tested. If all the tests from the xsl:when elements fail, the content from the xsl:otherwise element, if present, is instantiated. For example: <xsl:template match="/sites/site"> <xsl:choose> <xsl:when test="@num=1"> <xsl:value-of select="./url"/> </xsl:when> <xsl:when test="@num=3"> Site Number 3 </xsl:when> <xsl:otherwise> No matching Sites </xsl:otherwise> </xsl:choose> </xsl:template> This template tests the num attribute of the current site element in context. When using the following XML data with a style sheet containing the template: <?xml version="1.0" encoding="iso-8859-1"?> <sites> <site num="1"> <name>PHP</name> <url>http://www.php.net/</url> </site> <site num="2"> <name>XML C Parser</name> <url>http://www.xmlsoft.org/</url> </site> </sites> the resulting tree from the template would be as follows: http://www.php.net/ No matching Sites Sorting You can sort node sets within an xsl:apply-templates or xsl:for-each element using an xsl:sort element. When used within an xsl:for-each element, it must be the first child element but may come after an xsl:param element within the contents of an xsl:apply-templates element: CHAPTER 10 ■ EXTENSIBLE STYLESHEET LANGUAGE TRANSFORMATIONS (XSLT)360 6331_c10_final.qxd 2/16/06 4:43 PM Page 360 <xsl:sort select = string-expression lang = { nmtoken } data-type = { "text" | "number" | qname-but-not-ncname } order = { "ascending" | "descending" } case-order = { "upper-first" | "lower-first" } /> This element specifies the sort key for the node set from the parent element. You can use multiple xsl:sort elements to create sort keys, which are then processed in order. The sort key is created based on the resulting string from the expression defined in the select attribute. When not present, the select attribute defaults to ., causing the text value of the current node to be used as the sort key. For example: <xsl:for-each select="/people/person"> <xsl:sort select="./last-name" /> <xsl:sort select="./first-name" /> <p> <xsl:value-of select="./last-name"/>. <xsl:value-of select="./first-name"/> </p> <xsl:text> </xsl:text> </xsl:for-each> This for-each selects all person elements that are children of the people element, sorts them by last-name, and then sorts them by the first-name elements that are children of the person elements. This may sound a bit confusing and is much easier to see in an example. The xsl:text element has been inserted to allow line feeds to be inserted. The following XML data is used for the input: <people> <person> <first-name>John</first-name> <last-name>Smith</last-name> </person> <person> <first-name>Tom</first-name> <last-name>Jones</last-name> </person> <person> <first-name>Joe</first-name> <last-name>Smith</last-name> </person> </people> The resulting output is as follows: <p>Jones, Tom</p> <p>Smith, Joe</p> <p>Smith, John</p> CHAPTER 10 ■ EXTENSIBLE STYLESHEET LANGUAGE TRANSFORMATIONS (XSLT) 361 6331_c10_final.qxd 2/16/06 4:43 PM Page 361 The remaining optional attributes on this element control how the list of sort keys is sorted. The values for these attributes are all attribute template values so may be dynamically created. The lang Attribute The lang attribute specifies the language of the sort keys. The acceptable values for this attribute follow the same rules as those for an xml:lang attribute (http://www.w3.org/TR/ REC-xml/#sec-lang-tag). When not specified, the language is determined from the system environment. For example, to specify German as the language used for the sort keys, you would write the element as <xsl:sort lang="de" />. The data-type Attribute The data-type attribute specifies how the value of the resulting select expression should be interpreted for sorting purposes. The possible value for this attribute is text (which is the default value), number, or a QName. Any other value other than text or number should not be used. Using a QName for this attribute, which would be any valid QName other than the string text or number, is dependant upon a specific processor that understands what the value of the QName represents. The value text causes the data to be sorted lexicographically according to the language specified by the lang attribute. The order Attribute The order attribute accepts either ascending or descending for its value and determines whether the data should be ordered by the respective value. The default value for this attribute is ascending. The case-order Attribute The case-order attribute is valid only when the data-type is text, which of course is the default type for the data-type attribute. It can have the value lower-first or upper-first, and the default value is dependant upon the language (the value of the lang attribute) used for the keys. ■Note With the current version of libxslt, 1.1.14 (which is the XSLT library used for PHP 5), the case-order and lang attributes have not yet been implemented and will have no bearing on sort orders. Numbering The xsl:number element inserts formatted numbers into the results tree: <xsl:number level = "single" | "multiple" | "any" count = pattern from = pattern value = number-expression CHAPTER 10 ■ EXTENSIBLE STYLESHEET LANGUAGE TRANSFORMATIONS (XSLT)362 6331_c10_final.qxd 2/16/06 4:43 PM Page 362 format = { string } lang = { nmtoken } letter-value = { "alphabetic" | "traditional" } grouping-separator = { char } grouping-size = { number } /> The value attribute contains an expression that is converted to a number as if the num- ber function had been executed on the result of the expression. The number is then rounded to an integer and converted to a string based on the values of the format, lang, letter-value, grouping-separator, and grouping-size attributes. The actual process for the number-to- string conversion is beyond the scope of this chapter. You can find information about how to use these attributes to control the conversion in the XSLT specification at http:// www.w3.org/TR/xslt#convert. The grouping-separator and grouping-size attributes are both optional, but unless they both are specified on the element, either one is ignored by itself. These attributes define how and what separators are used for a number. For example, a comma is typically used to sepa- rate thousands within a number. Think of it in terms of the number_format() function in PHP, except it has no decimals or decimal places. The grouping-separator attribute specifies the character used to separate the digits, just like the thousands_sep parameter. Unlike the PHP function, the separator is not forced to separate thousands. Although it typically separates every three digits, it can separate at any number of digits. For example, the following: <xsl:number grouping-separator="," grouping-size="3" value="1000000" /> results in this: 1,000,000 Changing the separator character to the pound sign (#) and grouping on every two digits, like so: <xsl:number grouping-separator="#," grouping-size="2" value="1000000" /> results in the following: 1#00#00#00 When the value attribute is not specified, a number based on the position of the current node in the source XML document is inserted. The attributes level, count, and from can con- trol how this number is derived. The following descriptions come from the XSLT specifications: • The level attribute specifies what levels of the source tree should be considered; it has the value single, multiple, or any. The default is single. • The count attribute is a pattern that specifies what nodes should be counted at those levels. If the count attribute is not specified, then it defaults to the pattern that matches any node with the same node type as the current node and, if the current node has an expanded name, with the same expanded name as the current node. • The from attribute is a pattern that specifies where counting starts. CHAPTER 10 ■ EXTENSIBLE STYLESHEET LANGUAGE TRANSFORMATIONS (XSLT) 363 6331_c10_final.qxd 2/16/06 4:43 PM Page 363 The number constructed using the level, count, and from attributes is driven by the value of the level attribute. It determines which nodes will be used to match against the expressions defined in the count and from attributes. The following document demonstrates how to use these attributes: <book> <chapter> <section> <p>c1 s1 p1</p> </section> </chapter> <chapter> <section> <p>c2 s1 p1</p> </section> <section> <p>c2 s2 p1</p> <p node="context">c2 s2 p2</p> <p>c2 s2 p3</p> </section> <section> <p>c2 s3 p1</p> </section> </chapter> </book> The node that will be used as the context node is the p element having the attribute node with the value context. In XPath terms, the node can be identified by the expression /book/ chapter[2]/section[2]/p[@node='context']. When level="single", it searches for the first node in the ancestor-or-self axis that matches the count pattern. Once a node has been found, it counts the number of preceding siblings of this node that also match the count pattern and adds 1 to the count. The reason for the count being incremented by 1 is to take into account the first matching node. If the from attribute is specified, then the search is limited to ancestors of the node that are also descen- dants of the nearest ancestor matching the from pattern: <xsl:number level='single' count='p' /> When used within a style sheet against the context node, this would return 2. The first matching node ends up being the context node. The number of preceding sibling nodes that are named p, based on the pattern specified by the value of the count attribute, are then counted. In this case, you have only a single preceding sibling, and it matches, so the count is 1. You then add 1 to this number, which causes the final result to be 2. When level="multiple", the search works in a similar manner to single, except in this case, once a match is found, the search continues moving up one level in the hierarchy, allow- ing multiple nodes to be located. Counting is then performed for each of the located nodes using the pattern defined by the count attribute to match against previous siblings. The value returned is a list of numbers based on the results of each count. They are ordered based on the CHAPTER 10 ■ EXTENSIBLE STYLESHEET LANGUAGE TRANSFORMATIONS (XSLT)364 6331_c10_final.qxd 2/16/06 4:43 PM Page 364 location of the node, found from the search, in document order. The from attribute works in the same manner as described for using single: <xsl:number level='multiple' count='chapter|section|p' /> Here the count pattern will match elements named chapter, section, and p. This causes the search to locate the context node itself (matching on p), the parent element of p (match- ing on section), and the second chapter element in the document because it is the chapter node in the hierarchy of the context node. Based on document order, counting starts with the chapter element. The number of preceding siblings that match the count pattern is 1, which would be the first chapter element in the document. Then, 1 is then added to this to take into account the chapter node you are starting from, which results in 2. Counting is then per- formed using the next node in document order, which is the section element. There is only one preceding sibling that matches the pattern and adding 1 to this, the count also returns 2. Finally, the matching preceding siblings from the context node are counted. Again, only a single node matches, to which 1 is added, giving the final result of 2. The final value ulti- mately returned by this is 2.2.2. ■Note You can control the value returned using the format attribute. In this case, the attribute was not specified, and each count was separated by a decimal. If you used the attribute format="I.A.1", the result would have been II.B.2 because the first numeric in the result would be formatted using Roman numerals, indicated by I; the second numeric would be an alpha based on its numeric position from A, where A is position 1; and the last numeric is returned as a numeric based on the use of 1 for the third position in the format value. The xsl:number element is quite useful, especially in a case like this where you could use it as a label indicating the current chapter, section, and paragraph. When level="any", simply every node that matches the count pattern and that either is the context node or precedes the context node in document order is counted. This means the count includes preceding sibling nodes and ancestor nodes of the context, which match the count pattern, as well as nodes matching the pattern within the subtrees of those nodes. If the from attribute is specified, then only nodes matching the count pattern that fall within the scope of the node matching the from pattern and its subtree (excluding any node that comes after the context node in document order) and the context node are counted. For example: <xsl:number level='any' count='p' /> This returns the value 6. Only six p elements in the document consist of the context node and all the nodes that come before the context node in document order. The from attribute could limit this further to count only the p elements that fall within the context node and its ancestor chapter element: <xsl:number level='any' count='p' from="chapter" /> This would return the value 4 because the p elements within the first chapter element are not within the scope being matched even though they do precede the context node in docu- ment order. CHAPTER 10 ■ EXTENSIBLE STYLESHEET LANGUAGE TRANSFORMATIONS (XSLT) 365 6331_c10_final.qxd 2/16/06 4:43 PM Page 365 Using these attributes may be intimidating to those new to XPath and XSLT. It is a good idea to review the XPath material in Chapter 4, because it explains in more detail the organiza- tion of the tree, its axes, and its node sets. Using Variables and Parameters Variables and parameters allow values to be bound to a name using the elements xsl:variable and xsl:param. The actual names are a bit misleading because the difference between the two is that, once bound, the value for a variable cannot be changed; but when a value is bound to a parameter, the value acts only as the default value. Parameters can be passed to a template or style sheet that is used in place of the default values. For example: <xsl:variable name = qname select = expression> <! Content: template > </xsl:variable> <xsl:param name = qname select = expression> <! Content: template > </xsl:param> The name attribute is a required attribute for each of these elements. The value is a QName that specifies the name of the variable or parameter and is used to reference it within the style sheet. The select attribute is an optional attribute and can be used for an expression that, when evaluated, defines the value: <xsl:param name="phpText" select="PHP" /> This creates a parameter named phpText with a default value consisting of the string PHP. Because the value of the select attribute is an expression, the value can be any resulting type of an expression valid under XPath. This means variables and parameters could even be node sets. Using the select attribute is only one way to define a value. Each of these elements can also instantiate templates that become the value of the variable or parameter. Templates result in result trees, which consist of nodes. When defining the value within the content of the xsl:variable or xsl:param element, the element is bound to a resulting tree fragment. This means the resulting node set is wrapped within a root node, which is automatically cre- ated. If you are familiar with the DOM tree, it is equivalent to creating the resulting node set within a DOMDocumentFragment: <xsl:param name="phpText">PHP</xsl:param> Although this looks similar to the previous parameter of the same name, it is actually quite different. Using the select attribute select="PHP" results in the parameter phpText being bound to the string PHP. When the text PHP is used within the content of the xsl:param element, a text node with the value PHP is actually bound to the phpText parameter. Although this might not seem like a big difference, it actually could be, depending upon how the variable or parameter CHAPTER 10 ■ EXTENSIBLE STYLESHEET LANGUAGE TRANSFORMATIONS (XSLT)366 6331_c10_final.qxd 2/16/06 4:43 PM Page 366 is used because it’s not always the case that the node set operates in the same manner as a native string or numeric type would. When the select attribute is not present and the element contains no content, the value is defined as an empty string: <xsl:param name="emptyVar /> This is equivalent to writing the following: <xsl:param name="emptyVar" select="''" /> When referencing a variable or parameter, the name is prefixed with the dollar sign ($). Taking the previous binding for the emptyVar parameter, it would be used within an expression in the form of $emptyVar: <xsl:value-of select="$emptyVar" /> Setting Global Variables and Style Sheet Parameters Variables and parameters are used as top-level elements, meaning they are direct children of the xsl:stylesheet element, are declared globally, and are visible everywhere in the style sheet. As a result of parameters being able to be passed to style sheets and templates, top-level xsl:param elements declare parameter elements for the style sheet, which can be passed to the style sheet by an XSLT processor. The context of either of these types of elements, when residing as top-level elements, is the root node of the source document. This is something to keep in mind when writing any expressions for the values of these elements. It is also worthy to note that the values must be computed prior to the variable or parameter being referenced. For example: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:param name="x" select="1"/> <xsl:template match="/"> <value> <xsl:value-of select="$x" /> </value> </xsl:template> </xsl:stylesheet> When a document is processed with this style sheet, the default results are as follows: <value>1</value> The XSLT processor may pass a different value for the parameter named x, such as the value 5. This time, processing the document results in the following: <value>5</value> Setting Variables and Parameters in Templates Variables and parameters used within templates are local to those templates. In other words, they are visible to all sibling nodes and their descendants. All xsl:param elements must be declared as the first child elements of an xsl:template element. The xsl:variable elements, CHAPTER 10 ■ EXTENSIBLE STYLESHEET LANGUAGE TRANSFORMATIONS (XSLT) 367 6331_c10_final.qxd 2/16/06 4:43 PM Page 367 on the other hand, can be declared anywhere within the list of children of an xsl:template element. The parameter or variable, however, cannot be referenced by any elements that precede its declaration. For example: <! ERROR: variable used before being declared > <xsl:template name="mytemplate"> <xsl:value-of select="$x" /> <xsl:variable name="x" select="1" /> </xsl:template> Think of the xsl:variable and xsl:param elements in terms of variable scope in PHP. Global variables can be accessed from anywhere, including from within functions. Variables declared within functions are visible only within the function. It is also perfectly valid for a local variable to have the same name as a global variable. Within XSLT, this is called shadow- ing. For example: <! The Following is invalid > <xsl:template match="/"> <xsl:param name="x" select="1"/> <xsl:variable name="x" select="1"/> </xsl:template> This template is invalid because an xsl:variable element with the same name as an xsl:param element is within the same scope. To be able to reuse an xsl:variable or xsl:param name, they must be of different scope, or shadowed. For instance, the following style sheet binds a parameter within the global scope yet shadows the binding within a template: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:param name="x" select="1"/> <xsl:template match="/"> <xsl:param name="x" select="3"/> <value> <xsl:value-of select="$x" /> </value> </xsl:template> </xsl:stylesheet> This template is perfectly legal. The parameter, x, defined within the template shadows the global parameter binding. Within the template, unless a parameter of the same name is passed to it, the default value of 3 is used for the x parameter. Once the processor is finished with the template, the local parameter loses scope, causing the global parameter to once again take effect. The same rules apply to variables, although there is no possibility of a variable being passed to a template. A variable is considered bound and usable based on it being in scope. Passing Parameters to Templates Just like the XSLT processor can pass parameters to style sheets overriding the default parame- ter values, you can call templates with parameters to override default values bound within the template. You can use the xsl:with-param element for this purpose: CHAPTER 10 ■ EXTENSIBLE STYLESHEET LANGUAGE TRANSFORMATIONS (XSLT)368 6331_c10_final.qxd 2/16/06 4:43 PM Page 368 <xsl:with-param name = qname select = expression> <! Content: template > </xsl:with-param> This element is applicable within the content of an xsl:call-template or xsl:apply-templates element. The required name attribute is the name of the parameter, and you can use the optional select attribute to define the value. They work in the same fashion as an xsl:param element and use any child elements to specify content. The context for an expression used within the select attribute or template created within the content is the same as that used for the xsl:call-template or xsl:apply-templates element in which it resides. For example: <?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:param name="x" select="2"/> <xsl:template match="/"> <xsl:apply-templates select="sites/site"> <xsl:with-param name="x" select="count(.)" /> </xsl:apply-templates> </xsl:template> <xsl:template match="site"> <xsl:param name="x" select="10"/> <xsl:value-of select="$x" /> <xsl:text> </xsl:text> </xsl:template> </xsl:stylesheet> This is a bit more complex. The parameter x is bound globally with the default value of 2. The entry template, matching /, applies any templates of the site elements that are children of the sites element and passes a parameter x with the value being the count of the current node set. Based on this expression, the value will always be 1. The matching template also defines the parameter x with the value 10. This is a shadow binding since it is declared locally yet the style sheet has the global parameter x as well. The value 10 for the local parameter is just the default value. As you can see from the results, the value passed from the xsl:with- param element is what is used for the actual value of the parameter within the template: 1 1 1 1 The template processed four site elements, which caused 1 to be output for each ele- ment. The xsl:text element was used only to add line feeds to the results. CHAPTER 10 ■ EXTENSIBLE STYLESHEET LANGUAGE TRANSFORMATIONS (XSLT) 369 6331_c10_final.qxd 2/16/06 4:43 PM Page 369 [...]... encoding for the processor to use while creating the resulting document You can find detailed information about encoding, especially with respect to the support under PHP 5, in Chapter 5 Used within a style sheet, this would cause the processor to produce an XML document with the following XML declaration: < ?xml version="1.0"... document is handled when imported by the processor I will explain how to use these constants later in the “The cloneDocument Property” section Using the XSLTProcessor Class XSL is an object-oriented API and works using a single class The XSLTProcessor handles all the functionality to transform XML data into another form The API is simple, consisting of one property and nine methods, yet provides some... reimplementation of domxml, XML and XSLT 387 6331_c10_final.qxd 388 2/16/06 4:43 PM Page 388 CHAPTER 10 ■ EXTENSIBLE STYLESHEET LANGUAGE TRANSFORMATIONS (XSLT) were split into new extensions This is how the DOM and XSL extensions came about in PHP 5 Both domxml and the XSLT extension have been moved to PECL (http://pecl .php. net/), although neither has packages built for it, and both must be accessed... upon the XSLT processor Within PHP 5, any output from an xsl:message is captured as an error More particularly, an E_WARNING is generated with the output from the xsl:message as the error message Using PHP 5. 1, you can capture them using the new XML error handling by means of calling libxml_use_internal_errors(TRUE); This way, the messages will be contained within the message property of LibXMLError objects:... functionality The cloneDocument Property Earlier versions of libxslt (those prior to 1.1 .5) caused problems with the XML data document when using keys in a style sheet The problems resulted in a corrupt XML data document, making it useless for any further processing and possibly causing a crash Originally, prior to this being changed with libxslt 1.1 .5, the data document would be copied and the copy was used... The ToXML part might make you think that only XML will be returned, which is not the case when working with HTML All this method does is return the resulting tree as a string The ToXML is used to be consistent with the other XML methods (such as saveXML() in DOM and asXML() in SimpleXML) where the methods are just returning their tree, which happen to be XML data, as a string: string transformToXML(DOMDocument... The terminate attribute instructs the XSLT processor whether it should terminate upon encountering and after processing the xsl:message element The default value is no, so processing will continue, no E_WARNINGS will be issued, and no LibXMLError objects (explained in Chapter 5) will be captured The content of this element is the template used to create the XML fragment that becomes the message for... select="./name" /> The resulting tree can contain the following: PHP XML C Parser The PHP warnings or message properties of LibXMLError objects would contain the following: Debug: PHP Debug: XML C Parser Using Extensions Extensions, naturally, are a way of extending the regular capability of the XSLT processor They allow you to add your own custom functions, which are then callable... XSLT processor can create three types of output They are xml, html, and text, which are also the possible values for the method attribute By definition, the method attribute can also take a QName that must contain a prefix, but this is processor dependant and often not supported ■ Note The XSL extension in PHP 5 supports only the values xml, html, and text for the method attribute When this attribute... inner workings of SimpleXML SimpleXML has no concept of a document node The first SimpleXMLElement object is created from one of the simplexml_load_xxx() functions, and the resulting object refers to the document element To allow SimpleXML to interact with XSL, any SimpleXMLElement type object passed to this method automatically imports the document node associated with the SimpleXMLElement node This . following: <p> ;PHP& lt;/p> <p> ;XML C Parser</p> The PHP warnings or message properties of LibXMLError objects would contain the fol- lowing: Debug: PHP Debug: XML C Parser Using. upon encountering and after processing the xsl:message element. The default value is no, so pro- cessing will continue, no E_WARNINGS will be issued, and no LibXMLError objects (explained in Chapter 5) will. Using PHP 5. 1, you can capture them using the new XML error handling by means of calling libxml_use_internal_errors(TRUE);. This way, the messages will be contained within the message property

Ngày đăng: 12/08/2014, 13:21

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan