xml - Unanticipated <xsl:apply-imports/> behavior -


i've been trying figure out how best modularize xslt stylesheets facilitate re-use. hit upon idea of using <xsl:apply-imports/> way of introducing document-specific attributes standard tag transformations. not working way expected would, , can't begin fathom going on here. here simplified version of stylesheet:

<!-- main.xsl --> <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet  version="1.0"    xmlns:xsl="http://www.w3.org/1999/xsl/transform"    xmlns:fo="http://www.w3.org/1999/xsl/format">  <xsl:import href="html-customizations.xsl"/>  <xsl:output method="xml"    indent="yes"    omit-xml-declaration="no"/>  <xsl:template match="para">   <fo:block>       <xsl:attribute name="space-after">1em</xsl:attribute>       <xsl:apply-templates/>   </fo:block> </xsl:template>  <!-- =============== --> <!-- inline elements --> <!-- =============== -->  <xsl:template match="i">   <fo:inline font-style="italic">     <xsl:apply-imports/>     <xsl:apply-templates/>   </fo:inline> </xsl:template>  <!-- ================ --> <!--      tables      --> <!-- ================ -->  <xsl:template match="table">   <fo:table>     <xsl:apply-imports/>     <xsl:apply-templates/>   </fo:table> </xsl:template>  <xsl:template  match="tr">   <fo:table-row>     <xsl:apply-imports/>     <xsl:apply-templates/>   </fo:table-row> </xsl:template>  <xsl:template match="td | th">   <fo:table-cell>     <xsl:apply-imports/>     <xsl:apply-templates/>   </fo:table-cell> </xsl:template> </xsl:stylesheet> 

the imported stylesheet:

<!-- html-customizations.xsl --> <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet  version="1.0"    xmlns:xsl="http://www.w3.org/1999/xsl/transform"    xmlns:fo="http://www.w3.org/1999/xsl/format">  <xsl:template  match="td | th">   <xsl:attribute name="hyphenate">true</xsl:attribute> </xsl:template>  </xsl:stylesheet> 

here xml input file:

<!-- test.xml --> <para>   <table>     <tr><td>spongebob squarepants, <i>chair</i></td></tr>     <tr><td>patrick starfish, <i>vice cchair</i></td></tr>     <tr><td>squidword, <i>secretary</i></td></tr>   </table> </para> 

$ xalan -o out.xml test.xml main.xsl

out.xml: <?xml version="1.0" encoding="utf-8"?> <fo:block xmlns:fo="http://www.w3.org/1999/xsl/format" space-after="1em">   <fo:table>     <fo:table-row> <fo:table-cell hyphenate="true">spongebob squarepants, <fo:inline font-style="italic">chairchair</fo:inline> </fo:table-cell> <fo:table-cell hyphenate="true">spongebob squarepants, <fo:inline font-style="italic">chairchair</fo:inline> </fo:table-cell> </fo:table-row>     <fo:table-row> <fo:table-cell hyphenate="true">patrick starfish, <fo:inline font-style="italic">vice cchairvice cchair</fo:inline> </fo:table-cell> <fo:table-cell hyphenate="true">patrick starfish, <fo:inline font-style="italic">vice cchairvice cchair</fo:inline> </fo:table-cell> </fo:table-row>     <fo:table-row> <fo:table-cell hyphenate="true">squidword, <fo:inline font-style="italic">secretarysecretary</fo:inline> </fo:table-cell> <fo:table-cell hyphenate="true">squidword, <fo:inline font-style="italic">secretarysecretary</fo:inline> </fo:table-cell> </fo:table-row>      <fo:table-row> <fo:table-cell hyphenate="true">spongebob squarepants, <fo:inline font-style="italic">chairchair</fo:inline> ... ... 

as can see, every child of element matched template includes <xsl:apply-imports/> repeated! included imported stylesheet in order illustrate i'm trying do. if comment out import:

<!-- <xsl:import href="html-customizations.xsl"/> --> 

the repeating behavior same:

<?xml version="1.0" encoding="utf-8"?> <fo:block xmlns:fo="http://www.w3.org/1999/xsl/format" space-after="1em">   <fo:table>     <fo:table-row> <fo:table-cell>spongebob squarepants, <fo:inline font-style="italic">chairchair</fo:inline>spongebob squarepants, <fo:inline font-style="italic">chairchair</fo:inline> </fo:table-cell> <fo:table-cell>spongebob squarepants, <fo:inline font-style="italic">chairchair</fo:inline>spongebob squarepants, <fo:inline font-style="italic">chairchair</fo:inline> </fo:table-cell> </fo:table-row>     <fo:table-row> ... ... 

sans attribute i'm trying add imported stylesheet; i.e. presence of <xsl:apply-imports/> processing instruction causes output elements doubled. note not xalan problem -- same thing happens on msxml on windows 7.

any thoughts? counting on working, pulling hair out trying figure out how fix works.

btw, assumptions of how <xsl:apply-imports/> can used based on examples given under xsl:import section of michael kay's book. if knows of reference explains behavior i'm seeing above, please share.

i agree behaviour of apply-imports difficult understand. problem apply-imports always finds template matches current node, if user did not define it. in case, default template applies.

the following stylesheet works:

xslt stylesheet

<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet  version="1.0"     xmlns:xsl="http://www.w3.org/1999/xsl/transform"     xmlns:fo="http://www.w3.org/1999/xsl/format">      <xsl:import href="html-customizations.xsl"/>      <xsl:output method="xml"         indent="yes"         omit-xml-declaration="no"/>      <xsl:template match="para">         <fo:block>             <xsl:attribute name="space-after">1em</xsl:attribute>             <xsl:apply-templates/>         </fo:block>     </xsl:template>      <!-- =============== -->     <!-- inline elements -->     <!-- =============== -->      <xsl:template match="i">         <fo:inline font-style="italic">             <xsl:apply-templates/>         </fo:inline>     </xsl:template>      <!-- ================ -->     <!--      tables      -->     <!-- ================ -->      <xsl:template match="table">         <fo:table>              <xsl:apply-templates/>         </fo:table>     </xsl:template>      <xsl:template  match="tr">         <fo:table-row>              <xsl:apply-templates/>         </fo:table-row>     </xsl:template>      <xsl:template match="td | th">         <fo:table-cell>             <xsl:apply-imports/>             <xsl:apply-templates/>         </fo:table-cell>     </xsl:template> </xsl:stylesheet> 

as can see, have removed 2 apply-imports elements, leaving 1 inside template/@match='td | th'. then, output be

xml output

<?xml version="1.0" encoding="utf-8"?> <fo:block xmlns:fo="http://www.w3.org/1999/xsl/format" space-after="1em">     <fo:table>         <fo:table-row>          <fo:table-cell hyphenate="true">spongebob squarepants, <fo:inline font-style="italic">chairchair</fo:inline>          </fo:table-cell>       </fo:table-row>         <fo:table-row>          <fo:table-cell hyphenate="true">patrick starfish, <fo:inline font-style="italic">vice cchairvice cchair</fo:inline>          </fo:table-cell>       </fo:table-row>         <fo:table-row>          <fo:table-cell hyphenate="true">squidword, <fo:inline font-style="italic">secretarysecretary</fo:inline>          </fo:table-cell>       </fo:table-row>     </fo:table> </fo:block> 

what happening?

apply-imports looks template that

  • matches current node
  • matches current mode
  • is inside imported stylesheet

now, crucial bit is: instruction invoke built-in templates if no such template can found in imported stylesheet. in case of tr:

<xsl:template  match="tr">   <fo:table-row>     <xsl:apply-imports/>     <xsl:apply-templates/>   </fo:table-row> </xsl:template> 

the default action element nodes traversing , applying templates content, snippet above translates to

<xsl:template  match="tr">   <fo:table-row>     <xsl:apply-templates/>     <xsl:apply-templates/>   </fo:table-row> </xsl:template> 

and why output contains duplicates. assume understand why commenting out xsl:import did not help, otherwise i'm glad elaborate.


since asking reference, is explained in xslt 2.0 , xpath 2.0 programmer's reference michael kay, page 238.


Comments

Popular posts from this blog

php - failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request -

java - How to filter a backspace keyboard input -

java - Show Soft Keyboard when EditText Appears -