Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to match the processing-instruction element in XSLT?

I have some processing-instructions elements inside my xml content, for example :

<?legalnoticestart?>
<?sourcenotestart?>
<para>Content para</para>
<?sourcenoteend?>
<?literallayoutstart?>
<para>body content </para>
<?literallayoutend?>
<?legalnoticeend?>

How can i match these elements and get the content in the below required element format?

Required xml:

<legalnotice>
<sourcenote>
<p>Content para</p>
</sourcenote>
<literallayout>
<p>body content</p>
</literallayout>
</legalnotice>

Please advice....

Best Regards, Antony

like image 599
Antony Avatar asked Sep 02 '09 10:09

Antony


People also ask

What is the XSL processing-instruction element?

The xsl:processing-instruction element writes (generates) a processing instruction to the output. The content of this element becomes the text of the processing instruction.

Are XSLT processing instructions legal?

The resulting processing instruction is still perfectly legal XML.) As with xsl:comment elements, an xsl:processing-instruction element cannot be a top-level element -- if it's a child of an xsl:stylesheet element, an XSLT processor will ignore it.

How do I add processing instructions to an XSLT result tree?

An XSLT processor's default treatment of processing instructions in the source tree is to ignore them. Using the processing-instruction () function, your stylesheet can find processing instructions and add them to the result tree. For example, this template copies all processing instructions to the output with no changes.

How do you match a template in XSLT?

xsl:template element must have either@match attribute or @name attribute or both. An xsl:template element that has no match attribute must have no mode attribute and no priority attribute. Let’s re-write the above XSLT (<xsl:for-each) code with respect to Named Template (@name) and Match Template (@match).


2 Answers

By default, an XSLT processor will ignore PIs - to match them in order to do fun and useful things, you can use the processing-instruction match in your template:

<xsl:template match="processing-instruction('legalnoticestart')">
  <legalnotice><xsl:value-of select="."/></legalnotice>
</xsl:template>

For example, the following Stylesheet:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="doc">
        <xsl:apply-templates select="processing-instruction('legalnoticestart')" />
    </xsl:template>

    <xsl:template match="processing-instruction('legalnoticestart')">
        <legalnotice><xsl:value-of select="."/></legalnotice>
    </xsl:template>
</xsl:stylesheet>

With this document:

<doc>
   <?legalnoticestart?>
   <?legalnoticeend?>
</doc>

Yields:

<?xml version="1.0"?>
<legalnotice>
</legalnotice>
like image 93
butterchicken Avatar answered Oct 16 '22 20:10

butterchicken


This is inherently a bad design, you seem to be trying to match start/end tags but without using the methods available to if you were to use an actual xml element.

Whilst you can match the start/end processing instructions its difficult with xpath to locate the nodes between said processing instructions. If you have nesting or repeated such instructions it can become even more difficult. And at the end of the day, all this is doing is trying to replicate what xml already does without using xml?

like image 22
Chris Chilvers Avatar answered Oct 16 '22 21:10

Chris Chilvers