Processing Instructions XSLT

Processing Instruction

1. Processing Instructions
2. Handling processing instructions
3. xml processing instruction
4. Generating Processing Instructions
5. Accessing processing instructions
6. Generating a processing instruction
7. xsl processing instruction
8. How to get the name of the stylesheet from the PI in the XML document
9. template match on a specific processing instructions
10. Processing instruction content

1.

Processing Instructions

G Ken Holman



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

David Carlisle

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

Michael Kay


> 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

Mike Kay



> How to create a xsl processing
> instruction with an attribut using xslt?
>
> Sample:
>
> I would like to create something like this
> <?xml-stylesheet type="text/css" href="toto.xsl"?>

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

Jeni Tennison



> I have the following processing instructions throughout my xml file:
> <?FRAME LABEL='Introduction to IADS' SHOWNO='N'?>
>
> I need to be able to get the value of the LABEL attribute
> (Introduction to IADS). I am using IE 6.0. I can match the
> processing instruction, but I can't seem to get the individual
> attribute values. I have tried <xsl:value-of select="@label"/>, but
> this doesn't seem to work.

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=&apos;"), "&apos;")}">
    <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

Josh Canfield



> I need to have the following line in the resulting XML.
> <?mso-application progid="Excel.Sheet"?>

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

Mike Kay



> > <?xml-stylesheet type="text/xsl" href="test.xsl"?>

> Technically, this is illegal, as there is no MIME type
> text/xsl.

Correct.


> Well, last time I looked there was none.
> Should be text/xml.

No it shouldn't.


> application/xml might work too (untested).

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

Jeni Tennison



> Could somebody please tell me
> how to extract the name of a stylesheet from 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=&quot;'),
                             '&quot;')" />

9.

template match on a specific processing instructions

Josh Canfield


>I've been playing around with this, and haven't been able to figure out how
>to remove the processing instruction:

><?Pub Foobar?>

>without also removing others like:
><?Pub 12343?>

><xsl:template match="processing-instruction('Pub')">
></xsl:template>
>I've tried using if and choose statements with value-of select, but to no
>avail.  If anyone has any recommendations, I'd really appreciate it.

How about:

<xsl:template 
       match="processing-instruction('Pub')[.='Foobar']"/>

10.

Processing instruction content

Mike Kay




 > <?page 5?>
 > <?page 6?>
 > <?page 8?>
 > 
 > The style sheet should tell <?page 8?> is out of sequence.
 > 

Assuming you are applying templates to processing instructions:

<xsl:template match="processing-instruction('page')">
  <xsl:if
  test="preceding::processing-instruction('page')[1][number(.) 
	  &gt;=
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.)