How to do pagination of table with xslt? - xslt

I want to keep two rows together, without page break happening between them. My xslt script is as follow:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" exclude-result-prefixes="xs" xmlns:xs=http://www.w3.org/2001/XMLSchema xmlns:xsl=http://www.w3.org/1999/XSL/Transform>
<xsl:template priority="101" match="row[.//entry[#nameend='c2']/ph]">
<xsl:call-template name="row-keep-with-next"/>
</xsl:template>
<xsl:template name="row-keep-with-next">
<xsl:variable name="row" as="node()">
<topic class="- topic/tbody ">
<xsl:copy >
<xsl:sequence select="#* except #outputclass"/>
<xsl:attribute name="outputclass" select="string-join(('keep-with-next', tokenize(#outputclass, '\s+')), ' ')"/>
<xsl:sequence select="node()"/>
</xsl:copy>
</topic>
</xsl:variable>
<xsl:apply-templates select="$row"/>
</xsl:template>
</xsl:stylesheet>
But I still see page break happening. My css is as follows:
#media print
{ *[outputclass~="keep-with-next"] { page-break-after: avoid; }
*[outputclass~="keep-with-previous"] { page-break-before: avoid; }
*[outputclass~="top-of-page"] { page-break-before: always; } }
This is the sample on which I am trying to test:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE dita
PUBLIC "-//OASIS//DTD DITA Composite//EN" "dtd/ditabase.dtd">
<dita><!-- topic/titlealts not supplied within topic/topic --><!-- topic/prolog not supplied within topic/topic --><reference xmlns:ditaarch=http://dita.oasis-open.org/architecture/2005/ id="parameters_top"><title>Parts</title>
<refbody outputclass="db.sect2"><section>
<table id="paratable" pgwide="1" outputclass="PTable"><title outputclass="db.title">Basic Config</title>
<tgroup cols="2" outputclass="ParametersTable"><colspec colnum="1" colname="c1" colwidth="2*"/><colspec colnum="2" colname="c2" colwidth="5*"/>
<thead outputclass="db.thead"><row outputclass="db.row"><entry outputclass="db.entry">Label</entry><entry outputclass="db.entry">Description</entry></row></thead>
<tbody outputclass="db.tbody">
<row outputclass="db.row"><entry outputclass="db.entry" namest="c1" nameend="c2" align="center"><ph outputclass="db.phrase"> P Type </ph></entry></row>
<row outputclass="db.row"><entry outputclass="db.entry"><ph outputclass="db.phrase">Phy</ph></entry><entry outputclass="db.entry"><p outputclass="db.para"><ph outputclass="db.phrase">Select the type of PHY.</ph></p></entry></row>
<row outputclass="db.row"><entry outputclass="db.entry"><ph outputclass="db.phrase">Speed</ph></entry><entry outputclass="db.entry"><p outputclass="db.para">Link speed </p></entry></row></tbody></table></section></refbody></reference></dita>
I am trying to avoid pagebreak after row with "P Type".

Related

Index of the node selected not based on his parent

I have an xml like this one:
<?xml version="1.0" encoding="WINDOWS-1252" ?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<root>
<something>
<cd>a1</cd>
<cd>a2</cd>
</something>
<another>
<cd>b1</cd>
<cd>b2</cd>
<cd>b3</cd>
<cd>b1</cd>
<cd>b2</cd>
<cd>b3</cd>
<cd>b1</cd>
<cd>b2</cd>
</another>
</root>
I'm selecting all the cd nodes and trying to take the cds from 10 to 10 (1st, 11th, 21th...) this way:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html><body>
<xsl:apply-templates select="//cd" />
</body></html>
</xsl:template>
<xsl:template match="cd"/>
<xsl:template match="cd[position() mod 10 = 1]">
<div>
pos:<xsl:value-of select="position()"/>;
value:<xsl:value-of select="."/>
</div>
</xsl:template>
</xsl:stylesheet>
The output:
pos:1; value:a1
pos:3; value:b3
And the expected output:
pos:1; value:a1
pos:11; value:b11
The problem is that position() in the match is the node number based on his parent. So the position() of "b1" is 1 and not 3. Is there a function to know the index of the current node?
Thanks in advance.
//EDIT to extend the example
You can get a more accurate count by using xsl:number:
<xsl:template match="cd">
<div>pos: <xsl:number level="any"/></div>
</xsl:template>
You could also count the preceding cd elements:
<xsl:template match="cd">
<div>pos: <xsl:value-of select="count(preceding::cd)+1"/></div>
</xsl:template>
I prefer xsl:number, but I suppose it depends on how you're using the value. If you give a better example of what you're trying to do with that number, I can update my answer.
Example based on question update:
Input
<root>
<something>
<cd>a1</cd>
<cd>a2</cd>
</something>
<another>
<cd>b1</cd>
<cd>b2</cd>
<cd>b3</cd>
<cd>b1</cd>
<cd>b2</cd>
<cd>b3</cd>
<cd>b1</cd>
<cd>b2</cd>
</another>
<another>
<cd>c1</cd>
<cd>c2</cd>
<cd>c3</cd>
<cd>c1</cd>
<cd>c2</cd>
<cd>c3</cd>
<cd>c1</cd>
<cd>c2</cd>
</another>
</root>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html><body>
<xsl:apply-templates select="//cd" />
</body></html>
</xsl:template>
<xsl:template match="cd"/>
<xsl:template match="cd[(count(preceding::cd)+1) mod 10 = 1]">
<div>
pos:<xsl:value-of select="position()"/>;
value:<xsl:value-of select="."/>
</div>
</xsl:template>
</xsl:stylesheet>
Output
<html>
<body>
<div>
pos:1;
value:a1
</div>
<div>
pos:11;
value:c1
</div>
</body>
</html>
The position() in the match of template filters "cd"s based on position in its parent:
<xsl:template match="cd[position() mod (10) = 1]">
and the position() inside the template definition,
<div>pos:<xsl:value-of select="position()"/></div>
gives you the cd's sequence which the template has been applied for.
Thus, "position() mod (10) = 1" filters only those "cd"s which are 1st, 11th, 21st, etc. children of their parents.
Hence, you can remove the filter from xsl:template's match and put it inside like this:
<xsl:template match="cd">
<div>pos:<xsl:if test="position() mod 10 = 1">
<xsl:value-of select="position()"/>
</xsl:if>
</div>
</xsl:template>
This will save all the CDs in a variable. In the for-each, the context does not depend on the parent nodes so you will get the position among all CDs:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:variable name="all-cds" select="//cd" />
<xsl:template match="root">
<xsl:for-each select="$all-cds">
<div>pos: <xsl:value-of select="position()"/></div>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

XSL cross reference

I am stuck with a XSLT 1.0 problem. I tried to find info on StackOverflow but I couldn't apply the examples.
Here is the structure of my XML:
<XML>
<PR>
<AS>
<ID_AS>AS-001</ID_AS>
<FIRST>
<ID_CATALOG>Id-001</ID_CATALOG>
<STATUS>NOK</STATUS>
</FIRST>
<SECOND>
<ID_CATALOG>Id-002</ID_CATALOG>
<STATUS>OK</STATUS>
</SECOND>
</AS>
<AS>
<ID_AS>AS-002</ID_AS>
<FIRST>
<ID_CATALOG>Id-003</ID_CATALOG>
<STATUS>OK</STATUS>
</FIRST>
<SECOND>
<ID_CATALOG>Id-004</ID_CATALOG>
<STATUS>OK</STATUS>
</SECOND>
</AS>
</PR>
<METADATA>
<ID_CATALOG>Id-001</ID_CATALOG>
<ANGLES>32.25</ANGLES>
</METADATA>
<METADATA>
<ID_CATALOG>Id-002</ID_CATALOG>
<ANGLES>18.75</ANGLES>
</METADATA>
<METADATA>
<ID_CATALOG>Id-003</ID_CATALOG>
<ANGLES>5.23</ANGLES>
</METADATA>
<METADATA>
<ID_CATALOG>Id-004</ID_CATALOG>
<ANGLES>12.41</ANGLES>
</METADATA>
</XML>
I want to display for each AS, the FIRST/ID_CATALOG, FIRST/STATUS and ANGLES corresponding to the ID_CATALOG, then SECOND/etc.
The output would be similar to:
AS-001
Id-001 NOK 32.25
Id-002 OK 18.75
AS-002
Id-003 OK 5.23
Id-004 OK 12.41
I tried the following XSL but I only get the ANGLES for the first item
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns="http://earth.google.com/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:hma="http://earth.esa.int/hma" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink">
<xsl:output method="xml" indent="yes" encoding="ISO-8859-1"/>
<!--==================MAIN==================-->
<xsl:template match="/">
<html>
<body>
AS List:
<br/><br/>
<xsl:call-template name="ASandCo"/>
</body>
</html>
</xsl:template>
<!--==================TEMPLATES==================-->
<xsl:template name="ASandCo">
<AS>
<xsl:for-each select="XML/PR/AS">
<xsl:value-of select="ID_AS"/>
<br/>
<xsl:value-of select="FIRST/ID_CATALOG"/> - <xsl:value-of select="FIRST/STATUS"/> -
<xsl:if test="contains(/XML/METADATA/ID_CATALOG, FIRST/ID_CATALOG)">
<xsl:value-of select="/XML/METADATA/ANGLES"/>
</xsl:if>
<br/>
<xsl:value-of select="SECOND/ID_CATALOG"/> - <xsl:value-of select="SECOND/STATUS"/> -
<xsl:if test="contains(/XML/METADATA/ID_CATALOG, SECOND/ID_CATALOG)">
<xsl:value-of select="/XML/METADATA/ANGLES"/>
</xsl:if>
<br/><br/>
</xsl:for-each>
</AS>
</xsl:template>
</xsl:stylesheet>
This XSLT will be applied to very large XML files, so I am trying to find the most efficient way.
Thank you very much in advance!
It seems like you want to look up some metadata metadata based on the ID_CATALOG value.
An efficient way to do this is by using a key. You can define a key on the top level:
<xsl:key name="metadata-by-id_catalog" match="METADATA" use="ID_CATALOG"/>
And then you can look up the ANGLES value using the key for a given ID_CATALOG value like this:
<xsl:value-of select="key('metadata-by-id_catalog', FIRST/ID_CATALOG)/ANGLES"/>
and this:
<xsl:value-of select="key('metadata-by-id_catalog', SECOND/ID_CATALOG)/ANGLES"/>

How to Optimize XSLT for Referencing data in other XMLs

In an input XML file, along with Static Columns, columns expecting data from other files (reference)is also available.
But for each reference, the input xml has separate row with same ID or UID.
The output file has to have all references and relations in one row (based on the ID or UID)
I wrote the XSLT for this transformation also. This XSLT is faster when the row count is less (< 100 or < 200). But, as the count grows, the output xml generation taking long time (for count of 1000 rows, around 30 mins).
I am using
<xsl:for-each select="z:row/#ID[generate-id() = generate-id(key('UniqueID',.))]">
in the XSLT. Because for the same ID in each row of input xml, it has to check for multiple references (like section) and relations (like Child) and populate the same as columns
Input Raw XML File.
<xml xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:z="#RowsetSchema">
<rs:data>
<z:row UID="PARENT_001_1221AD_A878" GroupID="" GroupRel="" ID="37" Name="Outer Asset Details" RelProduct="Line1" RelUID="CHILD1_101_9899_9POOU99" RelName="CHILD1" RelType="Child" Size="22"/>
<z:row UID="PARENT_001_1221AD_A878" GroupID="" GroupRel="" ID="37" Name="Outer Asset Details" RelProduct="Line1" RelUID="CHILD2_201_5646546_9890PBS" RelName="CHILD1" RelType="Child" Size="22"/>
<z:row UID="PARENT_001_1221AD_A878" GroupID="" GroupRel="" ID="37" Name="Outer Asset Details" RelProduct="Line1" RelUID="SEC_999_99565_998AFSD" RelName="Hydraulic Section" RelType="Section" Size="22"/>
</rs:data>
Child.xml
<Child xsi:noNamespaceSchemaLocation="../XSD/Child.xsd" FILE="Child" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Row UID="CHILD1_101_9899_9POOU99">
<Name>CHILD1</Name>
<Description>This has details about the Hydraulic sections of the automobile</Description>
</Row>
<Row UID="CHILD2_201_5646546_9890PBS">
<Name>CHILD2</Name>
<Description>This has details about the manual sections of the automobile</Description>
</Row>
Section.xml
<Section xsi:noNamespaceSchemaLocation="../XSD/Section.xsd" FILE="Section" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Row UID="SEC_999_99565_998AFSD">
<Name>Hydraulic Section</Name>
<Description>This has details about the Sections in which the Hydraulic Systems are used.</Description>
</Row>
XSLT File
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema" exclude-result-prefixes="s dt z rs msxsl" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="UniqueID" match="z:row/#ID" use="."/>
<xsl:template match="/">
<Parent xsi:noNamespaceSchemaLocation="../XSD/Parent.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" FILE="Parent">
<xsl:for-each select="xml">
<xsl:apply-templates select="rs:data"/>
</xsl:for-each>
</Parent>
</xsl:template>
<xsl:template match="rs:data">
<xsl:for-each select="z:row/#ID[generate-id() = generate-id(key('UniqueID',.))]">
<xsl:variable name="FRId">
<xsl:value-of select="current()"/>
</xsl:variable>
<xsl:variable name="curNSet" select="//z:row[#ID=$FRId]"/>
<xsl:copy-of select="current()"/>
<Record>
<xsl:attribute name="UID"><xsl:value-of select="$curNSet/#UID"/></xsl:attribute>
<xsl:element name="Size">
<xsl:value-of select="$curNSet/#Size"/>
</xsl:element>
<xsl:element name="Child">
<xsl:apply-templates select="$curNSet[#RelType='Child']" mode="Relations">
<xsl:with-param name="RelType" select="'Child'"/>
<xsl:with-param name="DstFileName" select="'../Files/Child.xml'"/>
</xsl:apply-templates>
</xsl:element>
<xsl:element name="Section">
<xsl:apply-templates select="$curNSet[#RelType='Section']" mode="References">
<xsl:with-param name="RelType" select="'Section'"/>
<xsl:with-param name="DstFileName" select="'../Files/Section.xml'"/>
</xsl:apply-templates>
</xsl:element>
</Record>
</xsl:for-each>
</xsl:template>
<xsl:template match="z:row" mode="Relations">
<xsl:param name="RelType"/>
<xsl:param name="DstFileName"/>
<xsl:element name="{$RelType}">
<xsl:attribute name="DestinationKey"><xsl:value-of select="#RelUID"/></xsl:attribute>
<xsl:attribute name="RelFilePath"><xsl:value-of select="$DstFileName"/></xsl:attribute>
<xsl:attribute name="SequenceNumber"><xsl:value-of select="position()"/></xsl:attribute>
<xsl:value-of select="#RelName"/>
</xsl:element>
</xsl:template>
<xsl:template match="z:row" mode="References">
<xsl:param name="DstFileName"/>
<xsl:attribute name="DestinationKey"><xsl:value-of select="#RelUID"/></xsl:attribute>
<xsl:attribute name="RelFilePath"><xsl:value-of select="$DstFileName"/></xsl:attribute>
<xsl:attribute name="SequenceNumber"><xsl:value-of select="position()"/></xsl:attribute>
<xsl:value-of select="#RelName"/>
</xsl:template>
Output.xml
<Parent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../XSD/Parent.xsd" FILE="Parent" ID="37">
<Record UID="PARENT_001_1221AD_A878">
<Size>22</Size>
<Child>
<Child DestinationKey="CHILD1_101_9899_9POOU99" RelFilePath="../Files/Child.xml" SequenceNumber="1">CHILD1</Child>
<Child DestinationKey="CHILD2_201_5646546_9890PBS" RelFilePath="../Files/Child.xml" SequenceNumber="2">CHILD1</Child>
</Child>
<Section DestinationKey="SEC_999_99565_998AFSD" RelFilePath="../Files/Section.xml" SequenceNumber="1">Hydraulic Section</Section>
</Record>
Please help me in optimizing the XSLT, so that the output file is generated faster
Consider to use
<xsl:key name="UniqueID" match="z:row" use="#ID"/>
then
<xsl:for-each select="z:row/#ID[generate-id() = generate-id(key('UniqueID',.))]">
<xsl:variable name="FRId">
<xsl:value-of select="current()"/>
</xsl:variable>
<xsl:variable name="curNSet" select="//z:row[#ID=$FRId]"/>
can be replaced with
<xsl:for-each select="z:row[generate-id() = generate-id(key('UniqueID', #ID))]">
<xsl:variable name="FRId" select="#ID"/>
<xsl:variable name="curNSet" select="key('UniqueID', #ID"/>
I am not sure you need the variable FRId at all but defining it with a select attribute instead of a nested value-of is certainly consuming less resources.
To make
<xsl:apply-templates select="$curNSet[#RelType='Child']" mode="Relations">
more efficient define a key
<xsl:key name="rel" match="z:row" use="concat(#ID, '|', #RelType)"/>
then use
<xsl:apply-templates select="key('rel', concat(#ID, '|', 'Child')" mode="Relations">
Then use the same approach for the other apply-templates.
All of the above is untested but should give you an idea.

XSLT: Replace string with Abbreviations

I would like to know how to replace the string with the abbreviations.
My XML looks like below
<concept reltype="CONTAINS" name="Left Ventricular Major Axis Diastolic Dimension, 4-chamber view" type="NUM">
<code meaning="Left Ventricular Major Axis Diastolic Dimension, 4-chamber view" value="18074-5" schema="LN" />
<measurement value="5.7585187646">
<code value="cm" schema="UCUM" />
</measurement>
<content>
<concept reltype="HAS ACQ CONTEXT" name="Image Mode" type="CODE">
<code meaning="Image Mode" value="G-0373" schema="SRT" />
<code meaning="2D mode" value="G-03A2" schema="SRT" />
</concept>
</content>
</concept>
and I am selecting some value from the xml like,
<xsl:value-of select="concept/measurement/code/#value"/>
Now what I want is, I have to replace cm with centimeter. I have so many words like this. I would like to have a xml for abbreviations and replace from them.
I saw one similar example here.
Using a Map in XSL for expanding abbreviations
But it replaces node text, but I have text as attribute. Also, it would be better for me If I can find and replace when I select text using xsl:valueof select instead of having a separate xsl:template. Please help. I am new to xslt.
I have created XSLT v "1.1". For abbreviations I have created XML file as you have mentioned:
Abbreviation.xml:
<Abbreviations>
<Abbreviation>
<Short>cm</Short>
<Full>centimeter</Full>
</Abbreviation>
<Abbreviation>
<Short>m</Short>
<Full>meter</Full>
</Abbreviation>
</Abbreviations>
XSLT:
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml" />
<xsl:param name="AbbreviationDoc" select="document('Abbreviation.xml')"/>
<xsl:template match="/">
<xsl:call-template name="Convert">
<xsl:with-param name="present" select="concept/measurement/code/#value"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="Convert">
<xsl:param name="present"/>
<xsl:choose>
<xsl:when test="$AbbreviationDoc/Abbreviations/Abbreviation[Short = $present]">
<xsl:value-of select="$AbbreviationDoc/Abbreviations/Abbreviation[Short = $present]/Full"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$present"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
INPUT:
as you have given <xsl:value-of select="concept/measurement/code/#value"/>
OUTPUT:
centimeter
You just need to enhance this Abbreviation.xml to keep short and full value of abbreviation and call 'Convert' template with passing current value to get desired output.
Here a little shorter version:
- with abbreviations in xslt file
- make use of apply-templates with mode to make usage shorter.
But with xslt 1.0 node-set extension is required.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="abbreviations_txt">
<abbreviation abbrev="cm" >centimeter</abbreviation>
<abbreviation abbrev="m" >meter</abbreviation>
</xsl:variable>
<xsl:variable name="abbreviations" select="exsl:node-set($abbreviations_txt)" />
<xsl:template match="/">
<xsl:apply-templates select="concept/measurement/code/#value" mode="abbrev_to_text"/>
</xsl:template>
<xsl:template match="* | #*" mode="abbrev_to_text">
<xsl:variable name="abbrev" select="." />
<xsl:variable name="long_text" select="$abbreviations//abbreviation[#abbrev = $abbrev]/text()" />
<xsl:value-of select="$long_text"/>
<xsl:if test="not ($long_text)">
<xsl:value-of select="$abbrev"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

Extract text from "para" tag with embedded "para" children?

I'm using Altova's command-line xml processor on Windows to process a Help & Manual xml file. Help & Manual is help authoring software.
I'm extracting the text content from it using the following xslt. Specifically, I'm having an issue with the final para rule:
<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:strip-space elements="*" />
<xsl:template match="para[#styleclass='Heading1']">
<xsl:text>====== </xsl:text>
<xsl:value-of select="." />
<xsl:text> ======
</xsl:text>
</xsl:template>
<xsl:template match="para[#styleclass='Heading2']">
<xsl:text>===== </xsl:text>
<xsl:value-of select="." />
<xsl:text> =====
</xsl:text>
</xsl:template>
<xsl:template match="para">
<xsl:value-of select="." />
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="toggle">
<xsl:text>**</xsl:text>
<xsl:apply-templates />
<xsl:text>**
</xsl:text>
</xsl:template>
<xsl:template match="title" />
<xsl:template match="topic">
<xsl:apply-templates select="body" />
</xsl:template>
<xsl:template match="body">
<xsl:text>Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
</xsl:text>
<xsl:apply-templates />
</xsl:template>
</xsl:stylesheet>
I've run into an issue with the extraction of text from certain paragraph elements. Take for example this xml:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="../helpproject.xsl" ?>
<topic template="Default" lasteditedby="tlilley" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../helpproject.xsd">
<title translate="true">New Installs</title>
<keywords>
<keyword translate="true">Regional and Language Options</keyword>
</keywords>
<body>
<header>
<para styleclass="Heading1"><text styleclass="Heading1" translate="true">New Installs</text></para>
</header>
<para styleclass="Normal"><table rowcount="1" colcount="2" style="width:100%; cell-padding:6px; cell-spacing:0px; page-break-inside:auto; border-width:1px; border-spacing:0px; cell-border-width:0px; border-color:#000000; border-style:solid; background-color:#fffff0; head-row-background-color:none; alt-row-background-color:none;">
<tr style="vertical-align:top">
<td style="vertical-align:middle; width:96px; height:103px;">
<para styleclass="Normal" style="text-align:center;"><image src="books.png" scale="100.00%" styleclass="Image Caption"></image></para>
</td>
<td style="vertical-align:middle; width:1189px; height:103px;">
<para styleclass="Callouts"><text styleclass="Callouts" style="font-weight:bold;" translate="true">Documentation Convention</text></para>
<para styleclass="Callouts"><text styleclass="Callouts" translate="true">To make the examples concrete, we refer to the </text><var styleclass="Callouts">Add2Exchange</var><text styleclass="Callouts" translate="true"> Service Account as "zAdd2Exchange" throughout this document.  If your Service Account name is different, substitute that value for "zAdd2Exchange" in all commands and examples.  If you have named your account according to the recommended "zAdd2Exchange", then you may cut and paste any given commands as is.</text></para>
</td>
</tr>
</table></para>
</body>
</topic>
When the xslt is run on that paragraph, it pulls the text out but does so at the top paragraph element. The transform is supposed to add a pair of newlines to all extracted paragraphs, but doesn't have a chance to do so on the embedded <para> elements because the text is extracted at the parent para element.
Note that I don't care about the table tags, I just want to strip those.
Is there a way to construct the para rule so that it properly extracts the directly-owned text of a para element, as well as the text of any children para's, such that each extracted chunk gets the rule's newlines in the output text?
I think I've found the answer. Instead of value-of with the last para rule, I'm using apply-templates instead and that seems to catch them all.