Why is it not OK to put a xsl:value-of into a fo:block? - intellij-idea

I have the following XSL file:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output media-type="text" omit-xml-declaration="yes"/>
<xsl:template match="root/branch">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="simple"
page-height="29.7cm"
page-width="21cm"
margin-top="1cm"
margin-bottom="2cm"
margin-left="2.5cm"
margin-right="2.5cm">
<fo:region-body margin-top="3cm"/>
<fo:region-before extent="3cm"/>
<fo:region-after extent="1.5cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="simple">
<fo:flow flow-name="xsl-region-body">
<fo:block font-size="12pt"
font-family="sans-serif"
line-height="15pt"
space-after.optimum="3pt"
text-align="justify">
<xsl:value-of select="branch/greenLeave"/>
<xsl:value-of select="branch/yellowLeave"/>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
When I open it in IDEA IntelliJ, I get the following error message:
Does anybody know what is wrong here? I cannot find a plausible explanation.

Seems like the XSD for FOP which I downloaded from https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk/fop/src/foschema/fop.xsd lacked support for nested XSL-T statements.
As a workaround, I manually added a
<any processContent="skip"/>
to that XSD file at the right place.

Related

How to convert XSL To XSLT (in order to eventually convert to pdf)

i have an XML file that i am trying to convert to PDF.
i have an xsl file, but when i convert it to PDF it does not show it properly and the styling is not ok on the converted PDF
i've been told that in order to convert to PDF i need to use XSLT and not XSL.
i didn't find any converter or a guide on how to convert the XSL to XSLT.
Hopefuly someone here knows?
Many Thanks!
the converting itself to PDF is done with Magic XPI (Integration Software)
<?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 name="RestOfWorldPdf">
<xsl:param name="barcode_url" />
<xsl:param name="images_dir" />
<fo:block-container break-before="page"
border-style="solid"
border-width="1px"
border-collapse="collapse"
font-family="sans-serif"
top="0px"
left="0px"
width="270px"
height="405px">
<!-- Logo-->
<fo:block-container absolute-position="absolute"
top="0px"
left="0px"
width="91px"
height="49px"
border-collapse="collapse"
border-right-width="1px"
border-right-style="solid"
text-align="center">
<fo:block>
<fo:external-graphic src="url('logo.jpg')"
content-height="46px"/>
</fo:block>
</fo:block-container>
<!-- Market & Transport Type -->
<fo:block-container
absolute-position="absolute"
top="0px"
left="93px"
height="23px"
width="111px">
<fo:block font-weight="bold"
font-size="14pt"
text-align="left"
padding-top="2px">
<fo:inline padding-left="1px">
<xsl:value-of select="../consignmentLabelData/marketDisplay"/>
</fo:inline>
<xsl:text> / </xsl:text>
<fo:inline>
<xsl:value-of select="../consignmentLabelData/transportDisplay" />
</fo:inline>
</fo:block>
</fo:block-container>

How to set a color in xslt once for all fields

Can I set a variable or something to lets say "red" once and when i want some font to be red i just call that variable? that way i can edit the color of all specified text with ease for future possibilities. I'm new to xslt and appreciate any help. thank you.
Edit: adding some code with what i would want.
<?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:output method="xml" indent="yes" />
<xsl:template match="/">
<!--Probably declare the variable here-->
<!--Like <variable=outputcolor value="red" -->
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="A4-portrait"
page-height="29.7cm" page-width="21.0cm" margin="2cm">
<fo:region-body />
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4-portrait">
<fo:flow flow-name="xsl-region-body" font-family="Helvetica"
font-size="6pt">
<fo:block font-size="8pt" text-indent="5pt">
<fo:inline font-weight="bold"><xsl:text>Application Summary</xsl:text></fo:inline>
<!--Here i would like to make red a variable that i could possibly changed -->
<!--like fo:inline color="{outputcolor}"-->
<fo:inline color="red">
<xsl:value-of select="businessInfo/appSum" />
</fo:inline>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
Using an attribute-set is an option worth exploring. Another option is to do what you started to do:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<!--Probably declare the variable here-->
<xsl:variable name="outputcolor" select="'red'" />
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="A4-portrait"
page-height="29.7cm" page-width="21.0cm" margin="2cm">
<fo:region-body />
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4-portrait">
<fo:flow flow-name="xsl-region-body" font-family="Helvetica"
font-size="6pt">
<fo:block font-size="8pt" text-indent="5pt">
<fo:inline font-weight="bold"><xsl:text>Application Summary</xsl:text></fo:inline>
<!--Here i would like to make red a variable that i could possibly changed -->
<fo:inline color="{$outputcolor}">
<xsl:value-of select="businessInfo/appSum" />
</fo:inline>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
Note that declaring the variable at the top level of the template limits its scope to that template only. You can declare global variables (at the top level of the stylesheet, outside of any template) to make them available anywhere in the stylesheet.
You can define a named attribute set as a direct child of xsl:stylesheet, containing the attributes you want to reuse:
<xsl:attribute-set name="colouredText">
<xsl:attribute name="color">red</xsl:attribute>
<!-- you can set other attributes too: font-weight, font-style, ... -->
</xsl:attribute-set>
and then use it when creating elements with xsl:copy, xsl:element or with a literal result element:
<xsl:copy use-attribute-sets="colouredText">
...
</xsl:copy>
<xsl:element name="fo:inline" use-attribute-sets="colouredText">
...
</xsl:element>
<fo:inline xsl:use-attribute-sets="colouredText">
...
</fo:inline>
If the output requirements change ("Besides being red, important info must be bold also" / "Forget the color, just made them italic" / "Try using Comic Sans") you only need to adjust the attribute definitions inside the attribute-set, without having to modify the templates where these "styles" are applied.
The value of the xsl:use-attribute-sets attribute is a whitespace-separated list of attribute set names:
<xsl:attribute-set name="spacedText">
<xsl:attribute name="space-before">12pt</xsl:attribute>
<xsl:attribute name="space-after">12pt</xsl:attribute>
</xsl:attribute-set>
...
<fo:block xsl:use-attribute-sets="colouredText spacedText">
This block is both coloured and spaced!
</fo:block>
An attribute set can in turn refer to other sets:
<xsl:attribute-set name="colouredTitle" use-attribute-sets="colouredText">
<xsl:attribute name="font-size">16pt</xsl:attribute>
<xsl:attribute name="text-align">center</xsl:attribute>
</xsl:attribute-set>
The linked section of the XSL 1.0 specifications (or the corresponding section of the XSL 2.0 specifications) provides further information about how attribute sets can be extended and merged.

XSL-FO XSL-T footer onthe bottom of the last page

I have an xsl file to generate a pdf. I want to put a footer on the bottom of the last page. I tryed something like this:
<?xml version="1.0" encoding="windows-1252"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="windows-1252"/>
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<page-sequence-master master-name="pages">
<repeatable-page-master-alternatives>
<conditional-page-master-reference page-position="last" master-reference="last-page"/>
<conditional-page-master-reference master-reference="other-page"/>
</repeatable-page-master-alternatives>
</page-sequence-master>
<fo:simple-page-master master-name="A4" page-width="210mm" page-height="297mm" margin-top="1cm" margin-bottom="1cm"
margin-left="1cm" margin-right="1cm">
<fo:region-body margin-top="90mm" margin-bottom="80mm"/>
<fo:region-before extent="90mm"/>
<fo:region-after extent="80mm"/>
<fo:region-start/>
<fo:region-end/>
</fo:simple-page-master>
</fo:layout-master-set>
<html>
<fo:page-sequence master-reference="A4">
<fo:static-content flow-name="xsl-region-before">
<fo:block>
header
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
body
</fo:flow>
<fo:static-content flow-name="xsl-region-after">
<fo:block>
footer
</fo:block>
</fo:static-content>
</fo:page-sequence>
</html>
</fo:root>
</xsl:template>
The Footer appears at the end of the body and not at the end of the page, i dont know how to do it.
Your extent value on fo:region-after is the same as the margin-bottom value on the fo:region-body. If you reduce the extent, then the fo:region-after won't extend all the way up to the bottom of the fo:region-body.
See, e.g., the FO and PDF for 'Adding page numbers (page-number)' example at http://www.antennahouse.com/antenna1/comprehensive-xsl-fo-tutorials-and-samples-collection/. The FO includes:
<fo:simple-page-master page-height="150mm" page-width="210mm" margin-top="10mm"
margin-left="20mm" margin-right="20mm" margin-bottom="10mm" master-name="PageMaster">
<fo:region-before extent="15mm" />
<fo:region-after extent="15mm" />
<fo:region-body margin-top="0mm" margin-left="0mm" margin-right="0mm" margin-bottom="20mm" />
</fo:simple-page-master>
You can see that here there's a 5mm difference between the extent and the margin-bottom.

XSLT 1.0 String split template not working

I am new to XSLT and am having an issue with templates. I have an input xml file as follows:
<?xml version="1.0" encoding="UTF-8"?>
<Node>
<PHASE1_TYPE>LEFT,TOP</PHASE1_TYPE>
<PHASE1_HOL>TOK,ZUR,VIN</PHASE1_HOL>
<PHASE2_TYPE>RIGHT,BOTTOM</PHASE2_TYPE>
<PHASE2_HOL>CHF</PHASE2_HOL>
</Node>
My xslt is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template name="tokenize">
<xsl:param name="text" select="."/>
<xsl:param name="separator" select="','"/>
<xsl:choose>
<xsl:when test="not(contains($text, $separator))">
<Holiday>
<xsl:value-of select="normalize-space($text)"/>
</Holiday>
</xsl:when>
<xsl:otherwise>
<Holiday>
<xsl:value-of select="normalize-space(
substring-before($text, $separator))"/>
</Holiday>
<xsl:call-template name="tokenize">
<xsl:with-param name="text"
select="substring-after($text, $separator)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<Document>
<xsl:attribute name="xsi:noNamespaceSchemaLocation"
namespace="http://www.w3.org/2001/XMLSchema-instance"
>C:/usr/NONMAR~1/Output.xsd</xsl:attribute>
<xsl:for-each select="Node">
<Deal>
<DealType>
<xsl:value-of select="string(PHASE1_TYPE)"/>
</DealType>
<Holidays>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="string(PHASE1_HOL)"/>
<xsl:with-param name="separator" select="','"/>
</xsl:call-template>
</Holidays>
</Deal>
<Deal>
<DealType>
<xsl:value-of select="string(PHASE2_TYPE)"/>
</DealType>
<Holidays>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="string(PHASE2_HOL)"/>
<xsl:with-param name="separator" select="','"/>
</xsl:call-template>
</Holidays>
</Deal>
</xsl:for-each>
</Document>
</xsl:template>
</xsl:stylesheet>
After transformation, my output is:
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="C:/usr/NONMAR~1/Output.xsd">
<Deal>
<DealType>LEFT,TOP</DealType>
<Holidays>
<Holiday/>
</Holidays>
</Deal>
<Deal>
<DealType>RIGHT,BOTTOM</DealType>
<Holidays>
<Holiday/>
</Holidays>
</Deal>
</Document>
but the expected Output is :
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="C:/usr/NONMAR~1/Output.xsd">
<Deal>
<DealType>LEFT,TOP</DealType>
<Holidays>
<Holiday>TOK</Holiday>
<Holiday>ZUR</Holiday>
<Holiday>VIN</Holiday>
</Holidays>
</Deal>
<Deal>
<DealType>RIGHT,BOTTOM</DealType>
<Holidays>
<Holiday>CHF</Holiday>
</Holidays>
</Deal>
</Document>
I am using xslt 1.0 and do not want to use third party functions like EXSLT. Again, I am new to XSLT and do not have time right now to learn it. Would really appreciate if someone can tell me why this template is not working properly. Thanks!!
Sorry, but it's impossible to tell, from the information you provide.
On the plus side, you've taken some effort to cut your stylesheet and your sample input down in size and simplify them. That's good; I wish more new Stack Overflow users knew to do that.
On the minus side, the code you provide doesn't produce the output you show from the input you show. First of all, it's not well-formed; the end-tag for an xsl:for-each has gotten left out. And then that for-each, in the template for the document node, uses select="Node", which looks for elements named Node which are children of the document node -- but in your input, the only element child of the document node is named 'Root'. And your tokenization template wraps the individual tokens in item elements, instead of Holiday elements. When the first two slips are fixed, the stylesheet appears to produce the output you desire (modulo the Holiday/item issue):
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=
"C:/usr/NONMAR~1/Output.xsd">
<Deal>
<DealType>LEFT,TOP</DealType>
<Holidays>
<item>TOK</item>
<item>ZUR</item>
<item>VIN</item>
</Holidays>
</Deal>
<Deal>
<DealType>RIGHT,BOTTOM</DealType>
<Holidays>
<item>CHF</item>
</Holidays>
</Deal>
</Document>

can template match process params whose value is xml tag

The XSL below will extract "The Role of Magnetic Focus". but now i have to modify the xsl such that the input tags has to be passed as args.
Input XML:
<w:document>
<w:body>
<w:p>
<w:pPr>
<w:pStyle w:val="articletitle"/>
</w:pPr>
<w:r>
<w:t>The Role of Magnetic Focus</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="paragraph"/>
</w:pPr>
<w:r>
<w:t>All is well</w:t>
</w:r>
</w:p>
</w:body>
</w:document>
XSL:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"
>
<xsl:output method="text"/>
<xsl:template match="w:p"/>
<xsl:template match="w:p[w:pPr/w:pStyle/#w:val[matches(., concat('^(articletitle)$'),'i')]]">
<xsl:value-of select="."/><xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
I modified the above xsl as below, but i am not able to obtain the required output
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"
>
<xsl:param name="styleName" select="articletitle"/>
<xsl:param name="para" select="w:p"/>
<xsl:param name="parastyle" select="w:pPr/w:pStyle/#w:val"/>
<xsl:output method="text"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
<xsl:choose>
<xsl:when test="name() = $para">
<xsl:message><xsl:value-of select="name()"/></xsl:message>
<xsl:value-of select="name()"/>
</xsl:when>
</xsl:choose>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Please help.....
Just change:
<xsl:param name="para" select="w:p"/>
to:
<xsl:param name="para" select="'w:p'"/>