640 likes | 955 Vues
Orion Ifland 2008-05-15. Introduction to XSLT. Introduction to XSLT. Agenda The X* Ecosystem (XSL, XPath, XQuery...) XML Refresh/Terminology XPath: Addresses for XML documents XSLT Basics: template and value-of XSLT Loops: apply-templates and for-each
E N D
Orion Ifland 2008-05-15 Introduction to XSLT
Introduction to XSLT • Agenda The X* Ecosystem (XSL, XPath, XQuery...) XML Refresh/Terminology XPath: Addresses for XML documents XSLT Basics: template and value-of XSLT Loops: apply-templates and for-each XSLT Decisions: if and choose XSLT Variables: variable and param XSLT Extras: sort, copy-of, document… Why/When XSLT?
The X* Ecosystem • XSL(T): Extensible Stylesheet Language (Transforms) • Like a giant function with a domain of XML and a range of XML, HTML and Text • XSL-FO (Formatting Objects) is a related, graphics/print-oriented language • XPath: XML Path (addressing) • Like a filesystem path in an XML document • Also like RegEx
The X* Ecosystem • XQuery / XPath 2.0 / XSLT 2.0 • Kind of jumbled together • XQuery looks more like a mix of XSLT, SQL, and Javascript (including lots of XPath) • XMLNS (XML Namespaces) • Like programming language namespaces, distinguishes between elements/attributes with the same name • Used by XSLT and many other XML dialects
XML Refresh/Terminology • XML Nodes • Processing instruction: <?pi ... ?> • Element: <element /> or <element></element> • Attribute: <element attribute="value" /> • Comment: <!-- comment --> • Entity: & • Text node (just plain text)
XML Refresh/Terminology • XML Syntax Rules • Escape < > & (turn them into entities < > &) • Every document has exactly one root element • Attribute values are always quoted • Elements are case-sensitive (and are typically lowercase) • You don't have to put an xml processing instruction at the top of your document
XPath: Addresses for XML XPath Expressions /library /library/book /library/book/@name /library/book[@name="The Fourth Civilization"] /library/book[1] //book[2] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Expressions /library /library/book /library/book/@name /library/book[@name="The Fourth Civilization"] /library/book[1] //book[2] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Expressions /library /library/book /library/book/@name /library/book[@name="The Fourth Civilization"] /library/book[1] //book[2] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization"/> </library>
XPath: Addresses for XML XPath Expressions /library /library/book /library/book/@name /library/book[@name="The Fourth Civilization"] /library/book[1] //book[2] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library> Predicate
XPath: Addresses for XML XPath Expressions /library /library/book /library/book/@name /library/book[@name="The Fourth Civilization"] /library/book[1] //book[2] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Expressions /library /library/book /library/book/@name /library/book[@name="The Fourth Civilization"] /library/book[1] //book[2] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Node selectors /library/* /library/book[1]/text() /library/node()[1] . <library> <!-- comment --> <book>The Principles of Computer Hardware</book> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Node selectors /library/* /library/book[1]/text() /library/node()[1] . <library> <!-- comment --> <book>ThePrinciples of Computer Hardware</book> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Node selectors /library/* /library/book[1]/text() /library/node()[1] . <library> <!-- comment --> <book>The Principles of Computer Hardware</book> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Node selectors /library/* /library/book[1]/text() /library/node()[1] . <library> <!-- comment --> <book>The Principles of Computer Hardware</book> <book name="The Fourth Civilization" /> </library> Selects the "current" node
XPath: Addresses for XML XPath Axes /library/child::book(or /library/book for short) /descendent-or-self::book(or //book for short) //book[1]/parent::*(or //book[1]/.. for short) //book[2]/preceding-sibling::book //book[1]/attribute::name(or //book[1]/@name for short) <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Axes /library/child::book(or /library/book for short) /descendent-or-self::book(or //book for short) //book[1]/parent::*(or //book[1]/.. for short) //book[2]/preceding-sibling::book //book[1]/attribute::name(or //book[1]/@name for short) <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Axes /library/child::book(or /library/book for short) /descendent-or-self::book(or //book for short) //book[1]/parent::*(or //book[1]/.. for short) //book[2]/preceding-sibling::book //book[1]/attribute::name(or //book[1]/@name for short) <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Axes /library/child::book(or /library/book for short) /descendent-or-self::book(or //book for short) //book[1]/parent::*(or //book[1]/.. for short) //book[2]/preceding-sibling::book //book[1]/attribute::name(or //book[1]/@name for short) <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Axes /library/child::book(or /library/book for short) /descendent-or-self::book(or //book for short) //book[1]/parent::*(or //book[1]/.. for short) //book[2]/preceding-sibling::book //book[1]/attribute::name(or //book[1]/@name for short) <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Functions //book[last()] count(//book) name(/*) //book[contains(@name, "C++")] //book[not(contains(@name, "C++"))] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Functions //book[last()] count(//book) name(/*) //book[contains(@name, "C++")] //book[not(contains(@name, "C++"))] Returns: 2 <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Functions //book[last()] count(//book) name(/*) //book[contains(@name, "C++")] //book[not(contains(@name, "C++"))] Returns: "library" <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Functions //book[last()] count(//book) name(/*) //book[contains(@name, "C++")] //book[not(contains(@name, "C++"))] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Functions //book[last()] count(//book) name(/*) //book[contains(@name, "C++")] //book[not(contains(@name, "C++"))] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML Other Useful XPath Functions position() – provides the position in a list (nice for numbering a sequence of nodes) sum(xpath) – takes a sequence of nodes and adds up their numerical values – see also avg(), min(), max() concat(string, string, …) – exactly what you think string-length(string) – returns the number of characters substring(string, start[, length]) – the first char is at 1 translate(source-string, find-string, replace-string) – looks for individual chars and replaces themExample: translate("ABCD", "BD", "bd") "AbCd"
XPath: Addresses for XML XPath Operators //book[last() or contains(@name, "C++")] //book[string-length(@name) > 5] //book[1] | //book[2] Other operators: and, =, >, <=, >=, !=, +, -, *, div, mod Don't forget to escape < >! <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Operators //book[last() or contains(@name, "C++")] //book[string-length(@name) > 5] //book[1] | //book[2] Other operators: and, =, >, <=, >=, !=, +, -, *, div, mod Don't forget to escape < >! <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Operators //book[last() or contains(@name, "C++")] //book[string-length(@name) > 5] //book[1] | //book[2] Other operators: and, =, >, <=, >=, !=, +, -, *, div, mod Don't forget to escape < >! <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
XPath: Addresses for XML XPath Operators //book[last() or contains(@name, "C++")] //book[string-length(@name) > 5] //book[1] | //book[2] Other operators: and, =, >, <=, >=, !=, +, -, *, div, mod Don't forget to escape < >! <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
Try it out Make an XML file Make an XSLT file Run the transform and view the transformed data XSLT Basics <xml /> input <xsl:… /> transform <xml /> (or text) output
Sample XML <person> <name first="Neil" last="Armstrong" /> <quote>...one giant leap for mankind.</quote> </person> Sample Output Neil Armstrong said "...one giant leap for mankind." Sample XSLT <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" /> <xsl:template match="/person"> <xsl:value-of select="concat(name/@first, ' ', name/@last)" /> said " <xsl:value-of select="quote"/>" </xsl:template> </xsl:stylesheet> XSLT Basics
Sample XML <person> <name first="Neil" last="Armstrong" /> <quote>...one giant leap for mankind.</quote> </person> Sample Output Neil Armstrong said "...one giant leap for mankind." Sample XSLT <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" /> <xsl:template match="/person"> <xsl:value-of select="concat(name/@first, ' ', name/@last)" /> said " <xsl:value-of select="quote" />" </xsl:template> </xsl:stylesheet> XSLT Basics
Sample XML <person> <name first="Neil" last="Armstrong" /> <quote>...one giant leap for mankind.</quote> </person> Sample Output Neil Armstrong said "...one giant leap for mankind." Sample XSLT <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" /> <xsl:template match="/person"> <xsl:value-of select="concat(name/@first, ' ', name/@last)" /> said " <xsl:value-of select="quote"/>" </xsl:template> </xsl:stylesheet> XSLT Basics
Sample XML <person> <name first="Neil" last="Armstrong" /> <quote>...one giant leap for mankind. </quote> </person> Sample Output <html><head><title>Neil Armstrong</title></head> <body><blockquote>…one giant leap for mankind.</blockquote> </body></html> Sample XSLT HTML <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" /> <xsl:template match="/person"> <html><head><title> <xsl:value-of select="concat(name/@first, ' ', name/@last)" /> </title></head><body> <blockquote><xsl:value-of select="quote"/></blockquote> </body></html> </xsl:template> </xsl:stylesheet> XSLT Basics All well-formed
Sample XML <person> <name first="Neil" last="Armstrong" /> <quote>...one giant leap for mankind. </quote> </person> Sample Output <html><head><title>Neil Armstrong</title></head> <body><blockquote>…one giant leap for mankind.</blockquote> </body></html> Sample XSLT HTML <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" /> <xsl:template match="/person"> <html><head><title> <xsl:value-of select="concat(name/@first, ' ', name/@last)" /> </title></head><body> <blockquote><xsl:value-of select="quote"/></blockquote> </body></html> </xsl:template> </xsl:stylesheet> XSLT Basics
Sample XML <person> <name first="Neil" last="Armstrong" /> <quote>...one giant leap for mankind. </quote> </person> Sample Output <quote><speaker firstname="Neil" lastname="Armstrong"/> <text>…one giant leap for mankind.</text> </quote> Sample XSLT XML <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" /> <xsl:template match="/person"> <quote><speaker firstname="{name/@first}" lastname="{name/@last}"/> <text><xsl:value-of select="quote"/></text> </quote> </xsl:template> </xsl:stylesheet> XSLT Basics
Sample XML <person> <name first="Neil" last="Armstrong" /> <quote>...one giant leap for mankind. </quote> </person> Sample Output <quote><speaker firstname="Neil" lastname="Armstrong"/> <text>…one giant leap for mankind.</text> </quote> Sample XSLT XML <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" /> <xsl:template match="/person"> <quote><speaker firstname="{name/@first}" lastname="{name/@last}"/> <text><xsl:value-of select="quote"/></text> </quote> </xsl:template> </xsl:stylesheet> XSLT Basics
Sample XML <person> <name first="Neil" last="Armstrong" /> <quote>...one giant leap for mankind. </quote> </person> Sample Output <quote><speaker firstname="Neil" lastname="Armstrong"/> <text>…one giant leap for mankind.</text> </quote> Sample XSLT XML <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" /> <xsl:template match="/person"> <quote><speaker firstname="{name/@first}" lastname="{name/@last}"/> <text><xsl:value-of select="quote"/></text> </quote> </xsl:template> </xsl:stylesheet> XSLT Basics
Sample XML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> Sample XSLT HTML <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" /> <xsl:template match="/zoo"> <html><head><title>Zoo</title></head><body> <xsl:for-each select="*"> <h1> <xsl:value-of select="name(.)" /> </h1> </xsl:for-each> </body></html> </xsl:template> </xsl:stylesheet> XSLT Loops: for-each
Sample XML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> Result HTML <html><head><title>Zoo</title></head><body> <h1> birds </h1> <h1> mammals </h1> </body></html> XSLT Loops: for-each
Sample XML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> Sample XSLT HTML <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" /> <xsl:template match="/zoo"> <html><head><title>Zoo</title></head><body> <xsl:for-each select="*"> <h1><xsl:value-of select="name(.)" /></h1> <ul><xsl:for-each select="*"> <li><xsl:value-of select="name(.)" /> (<xsl:value-of select="@pop">)</li> </xsl:for-each></ul> </xsl:for-each> </body></html> </xsl:template> </xsl:stylesheet> XSLT Loops: for-each
Sample XML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> Result HTML <html><head><title>Zoo</title></head><body> <h1>birds</h1> <ul> <li>albatross (4)</li> … </ul> <h1>mammals</h1> <ul> <li>aardvark (5)</li> … </ul> </body></html> XSLT Loops: for-each
<xsl:template match="birds | mammals"> <h1><xsl:value-of select="name(.)" /></h1> <ul> <xsl:for-each select="*"> <li><xsl:value-of select="name(.)" /> (<xsl:value-of select="@pop"/>)</li> </xsl:for-each> </ul> </xsl:template> </xsl:stylesheet> XSLT Loops: apply-templates Sample XSLT <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" /> <xsl:template match="/zoo"> <html> <head><title>Zoo</title></head> <body> <xsl:apply-templates select="*" /> </body> </html> </xsl:template>
XML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> XSLT … <xsl:template match="birds | mammals"> <h1><xsl:value-of select="name(.)" /> </h1> <p>We have more than 2...</p> <xsl:if test="*[@pop > 2]"> <ul> <xsl:for-each select="*[@pop > 2]"> <li><xsl:value-of select="name(.)" /></li> </xsl:for-each> </ul> </xsl:if> </xsl:template> … XSLT Decisions: if
Sample XML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> Result HTML <html><head><title>Zoo</title></head><body> <h1>birds</h1> <p>We have more than 2...</p> <ul> <li>albatross</li> <li>chickadee</li> </ul> <h1>mammals</h1> <p>We have more than 2...</p> <ul> <li>aardvark</li> <li>bat</li> </ul> </body></html> XSLT Decisions: if
XML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> XSLT fragment <xsl:template match="birds | mammals"> <ul><xsl:for-each select="*"> <li><xsl:value-of select="name(.)" /> (<xsl:choose> <xsl:when test="@pop = 2">a couple</xsl:when> <xsl:when test="@pop <= 5">a few</xsl:when> <xsl:otherwise>many</xsl:otherwise> </xsl:choose>) </li> </xsl:for-each></ul> </xsl:template> XSLT Decisions: choose
Sample XML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> Result HTML <html><head><title>Zoo</title></head><body> <ul> <li>albatross (a few)</li> <li>buzzard (a couple)</li> <li>chickadee (many)</li> </ul> <ul> <li>aardvark (a few)</li> <li>bat (many)</li> <li>cheetah (a couple)</li> </ul> </body></html> XSLT Decisions: choose
XML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> XSLT fragment <xsl:template match="birds | mammals"> <xsl:variable name="total-animals" select="sum(*/@pop)" /> <ul><xsl:for-each select="*"> <li><xsl:value-of select="name(.)" /> (<xsl:value-of select="round(100 * @pop div $total-animals)"/>% of all <xsl:value-of select="name(..)"/>) </li> </xsl:for-each></ul> </xsl:template> XSLT Variables: variable