1 copyright (c) [2002]. roger l. costello. all rights reserved. using extension elements and...

34
1 (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello XML Technologies

Post on 22-Dec-2015

228 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

1Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

Using Extension Elements and Extension Functions with XSLT

and XPathRoger L. Costello

XML Technologies

Page 2: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

2Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

Extension Elements

• The XSL processor understands how to process xsl:template, xsl:apply-templates, xsl:if, xsl:for-each, etc– That is, it understands the vocabulary in the XSL

namespace

• XSL Processor implementers oftentimes provide additional elements that you may use in your stylesheet– These extension elements will belong to a namespace

defined by the implementer

Page 3: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

3Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

Example Extension Element: instruct the xsl processor to

output to another file• Many of the xsl processor implementers provide an

extension element that instructs the xsl processor to output the contents of the element to another file.– Thus, your stylesheet can generate multiple output files!

XSL Processor

XML

XSL

Page 4: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

4Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

Vendor-specific

• Each implementor gives the extension element a different name:– saxon calls it: output– xalan calls it: write

Page 5: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

5Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. How to use an extension element

1. Declare the namespace that the extension element belongs to:

saxon: xmlns:saxon="http://icl.com/saxon" xalan: xmlns:xalan="http://org.apache.xalan.xslt.extensions.Redirect"2. Indicate that any element that is namespace qualified by the prefix is an extension element, i.e., it has a specific meaning and should be processed using the implementer's code:

saxon: extension-element-prefixes="saxon" xalan: extension-element-prefixes="xalan"3. Use the extension element:

saxon: <saxon:output href="..."> -- anything in here will go to the file specified --- </saxon:output> xalan: <xalan:write file="..."> -- anything in here will go to the file specified --- </xalan:write>

Page 6: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

6Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

Problem

• Write a stylesheet which outputs the platinum members in one file, the gold members in another file, and the third file is an index to the other two files.

Page 7: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

7Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

FitnessCenter.xsl

FitnessCenter.xmlXSL

Processor

gold.xml

new-FitnessCenter.xml

platinum.xml

<PlatinumMembers href="platinum.xml"/><GoldMembers href="gold.xml"/>

Page 8: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

8Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

<xsl:copy-of select="xpath"/>

• This element instructs an xsl processor to copy to the output file the element selected by xpath, plus all its descendents.

<xsl:template match="Member"> <xsl:copy-of select="."/></xsl:template>

This instructs the xsl processor to copy everything from <Member> to </Member>i.e., the Member element and all its descendents.

Page 9: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

9Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. <?xml version="1.0"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://icl.com/saxon" extension-element-prefixes="saxon" version="1.0"> <xsl:output method="xml"/>

<xsl:template match="FitnessCenter"> <FitnessCenter> <PlatinumMembers href="platinum.xml"/> <saxon:output href="platinum.xml"> <PlatinumMembers> <xsl:for-each select="Member[@level='platinum']"> <xsl:copy-of select="."/> </xsl:for-each> </PlatinumMembers> </saxon:output> <GoldMembers href="gold.xml"/> <saxon:output href="gold.xml"> <GoldMembers> <xsl:for-each select="Member[@level='gold']"> <xsl:copy-of select="."/> </xsl:for-each> </GoldMembers> </saxon:output> </FitnessCenter> </xsl:template>

</xsl:stylesheet>

See extension-example01

Page 10: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

10Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

Don’t forget extension-element-prefixes

• The extension-element-prefixes is used to tell the xsl processor, "whenever you encounter an element with any of these prefixes listed here you are to treat it as an extension element, and process it using the implementer's code"

• If you fail to do so the xsl processor will simply output the element literally (see extension-example02)

Page 11: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

11Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

Extension Functions

• We have seen some of the functions that XSL provides: substring(), contains(), substring-before, etc.

• Many xsl processor implementers provide additional functions. You signify that a function is an extension function by namespace qualifying it.

Page 12: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

12Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

Dynamic (run-time) Evaluation

• Many xsl processor implementers give you an extension function that enables you to dynamically evaluate an expression.– That is, you can generate the expression on the

fly, or read it in from an external file.

• SAXON provides an extension function called evaluate to do this.

Page 13: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

13Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

FitnessCenter.xsl

FitnessCenter.xml XSLProcessor

checkFitnessCenter.xml

results.xml

This file contains expressions that are dynamically evaluated against FitnessCenter.xmlExample: provide an xpath expression that ensures that each Member's level attribute iseither Platinum or Gold, and nothing else.

Page 14: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

14Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. <?xml version="1.0"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://icl.com/saxon" extension-element-prefixes="saxon" version="1.0"> <xsl:output method="xml"/> <xsl:variable name="tests" select="document('checkFitnessCenter.xml')"/> <xsl:template match="/"> <xsl:variable name="here" select="."/> <FitnessCenter-results> <xsl:for-each select="$tests//xpath"> <result> <xsl:variable name="xpath" select="."/> <xsl:value-of select="$xpath"/> <xsl:for-each select="$here"> <xsl:choose> <xsl:when test="saxon:evaluate($xpath)"> <xsl:text> SUCCEEDED</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text> FAILED</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:for-each> <xsl:text></xsl:text> </result> </xsl:for-each> </FitnessCenter-results> </xsl:template>

</xsl:stylesheet>

Now any references is to elementsin checkFitnessCenter.xml

Takes us back to referencing elements in FitnessCenter.xml

Page 15: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

15Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

Using XSLT and XPath to Transform XML Documents that

contain NamespacesRoger L. Costello

XML Technologies

Page 16: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

16Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

ProblemSuppose that the document that we are processing is using namespaces:

<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="FitnessCenter.xsl"?>

<FitnessCenter xmlns="http://www.gym.com"> <Member level="platinum"> <Name>Jeff</Name> <Phone type="home">555-1234</Phone> <Phone type="work">555-4321</Phone> <FavoriteColor>lightgrey</FavoriteColor> </Member></FitnessCenter>

Note that we have a default namespace declaration. Thus, FitnessCenter, Member,Name, Phone, and FavoriteColor all belong to the http://www.gym.com namespace.

Page 17: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

17Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

<?xml version="1.0"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/>

<xsl:template match="/"> <HTML> <BODY> <xsl:apply-templates/> </BODY> </HTML> </xsl:template>

<xsl:template match="*"> <xsl:apply-templates/> </xsl:template>

<xsl:template match="Member">

Your name is: <xsl:value-of select="Name/text()"/> </xsl:template>

<xsl:template match="text()"> <!-- Do nothing --> </xsl:template>

</xsl:stylesheet>(see namespaces-example01)

Output:-- empty --

Page 18: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

18Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

Why is the output empty?

<xsl:template match="Member"> Your name is: <xsl:value-of select="Name/text()"/></xsl:template>

This template does not match any element in the instance document!This template matches on a Member element in no namespace.However, in our instance document the Member element is in thehttp://www.gym.org namespace, i.e.,

{http://www.gym.com}Member

Page 19: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

19Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

Namespace Terminology

{http://www.gym.com}Member

Expanded name = The combination of the namespace URI and the local name

Local name

Namespace URI

Page 20: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

20Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

Namespace Terminology (cont.)

<gym:FitnessCenter xmlns:gym="http://www.gym.com"> <gym:Member> …</gym:FitnessCenter>

<gym:Member>

prefix

Page 21: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

21Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

local-name()

• This is a built-in function which returns a string, corresponding to the local name of the element.

<xsl:template match="*"> Local name = <xsl:value-of select="local-name(.)"/> <xsl:apply-templates/></xsl:template>

Output:Local name = FitnessCenterLocal name = MemberLocal name = NameLocal name = PhoneLocal name = PhoneLocal name = FavoriteColor

(see namespaces-example02)

Page 22: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

22Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

<?xml version="1.0"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/>

<xsl:template match="/"> <HTML> <BODY> <xsl:apply-templates/> </BODY> </HTML> </xsl:template>

<xsl:template match="*"> <xsl:apply-templates/> </xsl:template>

<xsl:template match="*[local-name()='Member']">

Your name is: <xsl:value-of select=“*[local-name()=‘Name’]/text()"/> </xsl:template>

<xsl:template match="text()"> <!-- Do nothing --> </xsl:template>

</xsl:stylesheet>

(see namespaces-example03)

Output:Your name is: Jeff

Page 23: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

23Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

Alternatively<?xml version="1.0"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:gym="http://www.gym.com" version="1.0"> <xsl:output method="html"/>

<xsl:template match="/"> <HTML> <BODY> <xsl:apply-templates/> </BODY> </HTML> </xsl:template>

<xsl:template match="*"> <xsl:apply-templates/> </xsl:template>

<xsl:template match="gym:Member">

Your name is: <xsl:value-of select="gym:Name"/> </xsl:template>

<xsl:template match="text()"> <!-- Do nothing --> </xsl:template>

</xsl:stylesheet>

Declare the gym namespace

Match on the Member elementin the gym namespace

Select the Name element inthe gym namespace

(see namespaces-example04)

Page 24: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

24Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

namespace-uri()• This is a built-in function which returns a string

corresponding to the namespace URI of the node.

<xsl:template match="*"> Local name = <xsl:value-of select="local-name(.)"/> Namespace URI = <xsl:value-of select="namespace-uri(.)"/> <xsl:apply-templates/></xsl:template>

Output:Local name = FitnessCenterNamespace URI = http://www.gym.comLocal name = MemberNamespace URI = http://www.gym.comLocal name = NameNamespace URI = http://www.gym.comLocal name = PhoneNamespace URI = http://www.gym.com... (see namespaces-example05)

Page 25: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

25Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

name() Revisited

• We have seen the name() function before. It returns the name of the node. But what name does it return if the node is in a namespace?– Answer: it returns the element name and its

prefix (this is called the QName, for Qualified Name)

Page 26: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

26Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="FitnessCenter.xsl"?><gym:FitnessCenter xmlns:gym="http://www.gym.com"> <gym:Member level="platinum"> <gym:Name>Jeff</gym:Name> <gym:Phone type="home">555-1234</gym:Phone> <gym:Phone type="work">555-4321</gym:Phone> <gym:FavoriteColor>lightgrey</gym:FavoriteColor> </gym:Member></gym:FitnessCenter>

<xsl:template match="*">

Local name = <xsl:value-of select="local-name(.)"/>

Namespace URI = <xsl:value-of select="namespace-uri(.)"/>

Name = <xsl:value-of select="name(.)"/> <xsl:apply-templates/></xsl:template>

Page 27: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

27Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

Output:Local name = FitnessCenterNamespace URI = http://www.gym.comName = gym:FitnessCenterLocal name = MemberNamespace URI = http://www.gym.comName = gym:MemberLocal name = NameNamespace URI = http://www.gym.comName = gym:NameLocal name = PhoneNamespace URI = http://www.gym.comName = gym:PhoneLocal name = PhoneNamespace URI = http://www.gym.comName = gym:PhoneLocal name = FavoriteColorNamespace URI = http://www.gym.comName = gym:FavoriteColor

(see namespaces-example06)

Page 28: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

28Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

Identity transform - copying namespace declarations

• Recall our identity transform stylesheet:<xsl:template match="*">

<xsl:element name="{name(.)}">

<xsl:for-each select="@*">

<xsl:attribute name="{name(.)}">

<xsl:value-of select="."/> </xsl:attribute> </xsl:for-each> <xsl:apply-templates/> </xsl:element></xsl:template>

Iterate through eachattribute and add themas attributes onto the element.

Page 29: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

29Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

@* does not select namespace declarations!

• The @* will only select non-namespace declaration attributes. It will not select namespace declaration attributes

<Library xmlns="http://www.library.org" xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance" id="Boston Public Library">

This will be selected by @*

These will not be selected by @*

Page 30: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

30Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

Identity transformation for XML documents containing namespaces?

• So how do we create a stylesheet that can copy over namespace declarations, along with the other attributes?– Answer: use the <xsl:copy/> element

Page 31: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

31Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

<xsl:copy/>

• This element will copy the current element and all namespace declarations to the output file.

• Shallow copy (copy current node)• Cf: <xsl:copy-of />

– Deep copy (Copy current tree )– copy all attributes and namespace nodes– copy all descendants

Page 32: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

32Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

<?xml version="1.0"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml"/>

<xsl:template match="* | @*"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:apply-templates/> </xsl:copy> </xsl:template>

</xsl:stylesheet>

(see namespaces-example07)

The problem with this identity transform stylesheet is that it's not set upto allow us to make changes to elements/attributes.

Page 33: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

33Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

<?xml version="1.0"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml"/>

<xsl:template match="*"> <xsl:element name="{name(.)}"> <xsl:copy-of select="namespace::*" /> <xsl:for-each select="@*"> <xsl:attribute name="{name(.)}"> <xsl:value-of select="."/> </xsl:attribute> </xsl:for-each>

<xsl:apply-templates/>

</xsl:element> </xsl:template>

</xsl:stylesheet>

Error! Attemptingto create anelement in anamespace, butthe namespacehas not beendeclared yet!

Page 34: 1 Copyright (c) [2002]. Roger L. Costello. All Rights Reserved. Using Extension Elements and Extension Functions with XSLT and XPath Roger L. Costello

34Copyright (c) [2002]. Roger L. Costello. All Rights Reserved.

<?xml version="1.0"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml"/>

<xsl:template match="*"> <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}"> <xsl:copy-of select="namespace::*" /> <xsl:for-each select="@*"> <xsl:attribute name="{name(.)}" namespace="{namespace-uri(.)}"> <xsl:value-of select="."/> </xsl:attribute> </xsl:for-each>

<xsl:apply-templates/>

</xsl:element> </xsl:template>

</xsl:stylesheet>

Simultaneouslydeclare theelement and its namespace

Simultaneouslydeclare theattribute and its namespace

(see namespaces-example08)