Processing Instructions XSLT
1. | Processing Instructions |
input file: pi.xml <?xml version="1.0"?> <test> This is a test<?newline?>of text </test> Stylesheet: pi.xsl <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> <!--root rule--> <result> <test1> <xsl:apply-templates mode="test1"/> </test1> <test2> <xsl:apply-templates mode="test2"/> </test2> </result> </xsl:template> <xsl:template match="processing-instruction('newline')" mode="test1"> <br/> </xsl:template> <xsl:template match="processing-instruction()" mode="test2"> <br/> </xsl:template> </xsl:stylesheet> T:\ftemp>xt pi.xml pi.xsl <?xml version="1.0" encoding="utf-8"?> <result><test1> This is a test<br/>of text </test1><test2> This is a test<br/>of text </test2></result> T:\ftemp> | |
2. | Handling processing instructions |
How to turn <para> Some <?Pub _font FontColor="green"?>green<?Pub /_font?> text. </para> into <p> Some <font color="green">green</font> text. </p> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" > <xsl:template match="para"> <p> <xsl:apply-templates/> </p> </xsl:template> <xsl:template match="para/text() [count(following-sibling::processing-instruction()) mod 2 = 1]"/> <xsl:template match="text()" mode="yes"> <xsl:value-of select="."/> </xsl:template> <xsl:template match="processing-instruction('Pub')"> <xsl:variable name="x" select="count(following-sibling::processing-instruction())"/> <xsl:if test="$x mod 2 = 1"> <font color="{substring-before( substring-after(.,'FontColor="'),'"')}"> <xsl:apply-templates select="following-sibling::node()[ count(following-sibling::processing-instruction())=$x]" mode="yes"/> </font> </xsl:if> </xsl:template> </xsl:stylesheet> | |
3. | xml processing instruction |
> The xml-processing instruction (<?xml version='1.0'?> ... <?xml version='1.0'?> is an XML declaration, or a text declaration, it is not a processing instruction, despite the fact that it uses similar syntax. > I tried to insert a <xsl:processing-instruction name='xml'/> > into the final > output tree just before copying the node-set. This however is > not allowed. Correct: because processing instructions named "xml" are not allowed, to prevent confusion with XML declarations and text declarations. | |
4. | Generating Processing Instructions |
Processing instructions do not contain attributes. Some processing instructions, like this one, contain "pseudo-attributes", but they are not recognized as attributes by the XML parser, by the infoset, or by the XPath data model. They are just text. So you create them as text: <xsl:processing-instruction name="xml-stylesheet"> <xsl:text>type="text/css" </xsl:text> <xsl:text>href="</xsl:text> <xsl:value-of select="$href"/> <xsl:text>"</xsl:text> </xsl:processing-instruction> | |
5. | Accessing processing instructions |
The "attributes" in processing instructions aren't actually attributes -- they just look like them. Noramally people refer to these kinds of "attributes" as "pseudo-attributes" to emphasise that fact. As far as the XPath data model is concerned, the only information you can get about a processing instruction is its target (or name -- 'FRAME' in this case), its value ("LABEL='Introduction to IADS' SHOWNO='N'") and its location in the node tree. Pulling the pseudo-attributes out of the processing instruction, then, involves the same kind of code as you'd use to parse any structured string. To get the value of the LABEL pseudo-attribute, for example, you could use: <xsl:template match="pi('FRAME')"> <A name='{substring-before( substring-after(., "LABEL='"), "'")}"> <xsl:value-of select="." /> </A> </xsl:template> (This assumes that you're using apostrophes rather than double-quotes around the values of the pseudo-attribute.) | |
6. | Generating a processing instruction |
Use the processing instruction element: W3C xslt <xsl:processing-instruction name="mso-application">progid="Excel.Sheet"</xsl:processing-instruction> Check out the Mulberry quickref, it contains a quick list of available elements. mulberrytech.com Then if you want to know more about an element, try the XSLT spec: W3C XSLT | |
7. | xsl processing instruction |
Correct.
No it shouldn't.
Unlikely. The correct type is application/xslt+xml, per RFC 3023. It should be used everywhere. The only type you can effectively use in an xml-stylesheet processing instruction at this time, however, is text/xsl, because that's all that the browsers will recognize, AFAIK. We will never be rid of text/xsl, unfortunately. If IE started supporting the correct type in their next release, we might finally start to see text/xsl fade in about 3 years, when people stop worrying about keeping their stuff working in the older browsers. Of course, the whole notion of hard-coding a stylesheet reference in an XML document is a source of controversy. It is almost exclusively used to let a browser load a data source directly through a standard HTTP GET and to force a particular rendering of that data. This is a problem that could have been, and has been, solved in other, arguably more intelligent ways. | |
8. | How to get the name of the stylesheet from the PI in the XML document |
I assume that your XML document includes a <?xml-stylesheet?> processing instruction that points to the stylesheet that you want to get the name of? If so, you can locate that PI using: <xsl:variable name="PI" select="/processing-instruction('xml-stylesheet')" /> and then get the stylesheet name by string processing the value of the PI. Assuming the PI uses double quotes around the href pseudo-attribute value, for example, you can use: <xsl:value-of select="substring-before(substring-after($PI, 'href="'), '"')" /> | |
9. | template match on a specific processing instructions |
How about: <xsl:template match="processing-instruction('Pub')[.='Foobar']"/> | |
10. | Processing instruction content |
Assuming you are applying templates to processing instructions: <xsl:template match="processing-instruction('page')"> <xsl:if test="preceding::processing-instruction('page')[1][number(.) >= number(current())]"> <xsl:message>error</xsl:message> </xsl:if> </xsl:template> (The call to number() isn't needed in XSLT 1.0. It is needed in 2.0, because otherwise the values will be compared as strings. The condition will always be false if the value is non-numeric, you might want a different error message for that case. The predicate [1] is for performance reasons only.) |