I'm creating a piece of software that should let me update a value in an SQLite DB.
The problem is, this value contains a lot symbols (originally an xml AS value).
I've tried refractor this but I'm just not able to. Is there a faster way to do so maybe?
Thank you in advance!
The query:
cmd.CommandText =
"UPDATE main.PRINTOUT_TEMPLATES SET TEMPLATE =
<?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"
xmlns:pos="tcpos"\>
<xsl:strip-space elements="\*"/\>
<xsl:output method="html" version="4.0" indent="no"/\>
<xsl:template match="/transaction"\>
<xsl:call-template name="Transaction"\>
</xsl:call-template\>
</xsl:template\>
<xsl:template name="Transaction"\>
<xsl:variable name="Acrelec_sepaator" select="''\_______________________________________\_''"/\>
<!-- If transaction has no items do not print -->
<xsl:choose\>
<xsl:when test="articles-number != 0"\>
<!-- Send Drawer pulse -->
<!--27,112,48,255,255 -->
<SETUP CharsPerLine="40" LeftMargin="5" RightMargin="80" FontA="Lucida Console" FontB="Verdana"\>\</SETUP\>
<B\>\<HIGH\>\<CENTER\>\<xsl:value-of select="pos:translate(''Ceci n’est pas un ticket'')"/\>\</CENTER\>\</HIGH\>\</B\>
<BR/\>
<B\>\<HIGH\>\<CENTER\>\<xsl:value-of select="pos:translate(''de caisse TVA valable'')"/\>\</CENTER\>\</HIGH\>\</B\>
<BR/\>
<!-- information for the operator in the kitchen -->
<B\>\<HIGH\>
<xsl:if test="table/code != 0"\>
<LTAB col="2"\>\<xsl:value-of select="pos:translate(''Salle:'')"/\>\</LTAB\>
<LTAB col="22"\>\<xsl:value-of select="table/hall-code"/\>\</LTAB\>\<BR/\>
<LTAB col="2"\>\<xsl:value-of select="pos:translate(''Table:'')"/\>\</LTAB\>
<LTAB col="22"\>\<xsl:value-of select="table/code"/\>\</LTAB\>\<BR/\>
</xsl:if\>
<xsl:if test="trans-num"\>
<LTAB col="2"\>\<xsl:value-of select="pos:translate(''Transaction:'')"/\>\</LTAB\>
<LTAB col="22"\>\<xsl:value-of select="trans-num"/\>\</LTAB\>\<BR/\>
</xsl:if\>
<xsl:if test="cashier/description"\>
<LTAB col="2"><xsl:value-of select="pos:translate(''Opérateur:'')"/></LTAB>
<LTAB col="22"><xsl:value-of select="cashier/description"/></LTAB>
</xsl:if\>
</HIGH\>\</B\>
<xsl:if test="trans-item"\>
<!-- Print the description of the Name
\<LTAB col=''2''\>\<xsl:value-of select="pos:translate(''Produit:'')"/\>\</LTAB\>
--\>
<BR/\>\<BR/\>
<xsl:for-each select="trans-item"\>
<xsl:choose>
<!-- Normal articles layout -->
<xsl:when test="#type=''article'' or #type=''menu''">
<xsl:if test="is-addition=''false'' or #type=''menu''">
<u>
<CENTER><xsl:value-of select="$Acrelec_sepaator"/></CENTER><BR/> <BR/>
<HIGH>
<xsl:if test = "quantity">
<RTAB col=''2''><xsl:value-of select="pos:numFormat(quantity,'''')"/></RTAB>
<RTAB col="3"><xsl:value-of select="pos:translate(''x'')"/></RTAB>
</xsl:if>
<xsl:if test = "quantity = 0">
<RTAB col=''2''><xsl:value-of select="1"/></RTAB>
<RTAB col="3"><xsl:value-of select="pos:translate(''x'')"/></RTAB>
</xsl:if>
<xsl:if test="weight > 0">
<RTAB col=''30''><xsl:value-of select="weight"/></RTAB>
<RTAB col="32"><xsl:value-of select="pos:translate(''kg'')"/></RTAB>
</xsl:if>
<LTAB col=''5''><xsl:value-of select="description"/></LTAB>
</HIGH>
</u>
</xsl:if>
<xsl:if test="is-addition=''true''">
<HIGH>
<xsl:if test = "quantity">
<RTAB col=''4''><xsl:value-of select="pos:numFormat(quantity,'''')"/></RTAB>
<RTAB col="5"><xsl:value-of select="pos:translate(''x'')"/></RTAB>
</xsl:if>
<xsl:if test = "quantity = 0">
<RTAB col=''4''><xsl:value-of select="1"/></RTAB>
<RTAB col="5"><xsl:value-of select="pos:translate(''x'')"/></RTAB>
</xsl:if>
<LTAB col=''7''><xsl:value-of select="description"/></LTAB></HIGH>
</xsl:if>
<!-- <RTAB col=''40''><xsl:value-of select="pos:numFormat(total-price,''0.00'')"/></RTAB> -->
<BR/> <!-- ||| END OF THE ARTICLE LIST ||| -->
</xsl:when>
<!-- Article comments layout -->
<xsl:when test="#type=''comment''">
<xsl:if test="quantity = 1">
<B><FONTB><LTAB col=''6''><xsl:value-of select="description"/></LTAB></FONTB><BR/></B>
</xsl:if>
<xsl:if test="quantity != 1">
<FONTB><LTAB col=''6''><xsl:value-of select="concat(quantity,'' X '',description)"/></LTAB></FONTB><BR/>
</xsl:if>
</xsl:when>
<!-- Menu articles layout -->
<xsl:when test="#type=''menu-article''">
<xsl:if test="is-addition=''false'' or #type=''menu''">
<HIGH>
<xsl:if test = "quantity">
<RTAB col=''4''><xsl:value-of select="pos:numFormat(quantity,'''')"/></RTAB>
<RTAB col="5"><xsl:value-of select="pos:translate(''x'')"/></RTAB>
</xsl:if>
<xsl:if test = "quantity = 0">
<RTAB col=''4''><xsl:value-of select="1"/></RTAB>
<RTAB col="5"><xsl:value-of select="pos:translate(''x'')"/></RTAB>
</xsl:if>
<xsl:if test="weight > 0">
<RTAB col=''30''><xsl:value-of select="weight"/></RTAB>
<RTAB col="32"><xsl:value-of select="pos:translate(''kg'')"/></RTAB>
</xsl:if>
<LTAB col=''7''><xsl:value-of select="description"/></LTAB>
</HIGH>
</xsl:if>
<xsl:if test="is-addition=''true''">
<HIGH>
<xsl:if test = "quantity">
<RTAB col=''6''><xsl:value-of select="pos:numFormat(quantity,'''')"/></RTAB>
<RTAB col="7"><xsl:value-of select="pos:translate(''x'')"/></RTAB>
</xsl:if>
<xsl:if test = "quantity = 0">
<RTAB col=''6''><xsl:value-of select="1"/></RTAB>
<RTAB col="7"><xsl:value-of select="pos:translate(''x'')"/></RTAB>
</xsl:if>
<LTAB col=''9''><xsl:value-of select="description"/></LTAB>
</HIGH>
</xsl:if>
<BR/>
</xsl:when>
</xsl:choose>
<xsl:if test="article-causal-description!=''''">
<B><LTAB col=''6''><xsl:value-of select="article-causal-description"/></LTAB></B>
<BR/>
<BR/>
<CENTER><xsl:value-of select="$Acrelec_sepaator"/></CENTER>
<BR/>
</xsl:if>
</xsl:for-each\>
</xsl:if\>
<xsl:if test="delete-type or resumed-transaction"\>
<xsl:if test="resumed-transaction/resume-type = ''stornotransaction'' or delete-type = ''deleted''"\>
<BR/\>
<LTAB col=''1''\>
<xsl:value-of select="pos:translate(''Raison \\ Description'')"/\>
</LTAB\>
<BR/\>\<BR/\>\<BR/\>\<BR/\>\<BR/\>
<BR/\>
<LTAB col=''1''\>\<xsl:value-of select="pos:translate(''-----------------------------------------'')"/\> \</LTAB\>
<BR/\>\<BR/\>
</xsl:if\>
</xsl:if\>
<BIG\>\<CENTER\>\<xsl:value-of select="causal/description"/\>\</CENTER\>\</BIG\>
<!-- TILL TICKET NUMBER --\>
<B\>\<BIG\>\<CENTER\>\<xsl:value-of select="concat(pos:translate(''Ticket # ''), pos:numFormat(trans-num ,''0000''))"/\>\</CENTER\>\<BR/\>\</BIG\>\</B\>
<!-- PRINT ''TAKE AWAY'' OR ''EAT IN'' -->
<B>
<BIG>
<CENTER>
<xsl:choose>
<xsl:when test="pricelevel-code = 2">
<xsl:value-of select="''Sur Place''"/>
</xsl:when>
<xsl:when test="pricelevel-code = 3">
<xsl:value-of select="''À Emporter''"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="''? - Please Check''"/>
</xsl:otherwise>
</xsl:choose>
</CENTER>
</BIG>
</B>
<BR/\>\<BR/\>
<!-- PRINT ''DRIVE'' OR ''COUNTER'' -->
<xsl:choose>
<xsl:when test="till/code = 101">
<B><BIG><CENTER><xsl:value-of select="''DRIVE''"/></CENTER><BR/></BIG></B>
</xsl:when>
<xsl:when test="till/code = 103">
<B><BIG><CENTER><xsl:value-of select="''COUNTER''"/></CENTER><BR/></BIG></B>
</xsl:when>
<xsl:when test="till/code = ''201'' or ''202'' or ''203'' or ''204'' or ''205'' or ''206''">
<B><BIG><CENTER><xsl:value-of select="''SELF SERVICE''"/></CENTER><BR/></BIG></B>
</xsl:when>
</xsl:choose>
<BR/\>\<BR/\>
<!-- Print the transaction comment -->
<xsl:if test="transaction-comment != ''''"\>
<BIG\>\<CENTER\>\<xsl:value-of select="concat(pos:translate(''TENT: ''),transaction-comment)"/\>\</CENTER\>\</BIG\>\<BR/\>
</xsl:if\>
<!-- Date, Time and Till-->
<HIGH>
<LTAB col=''1''><xsl:value-of select="pos:translate(''Date:'')"/></LTAB>
<LTAB col=''7''><xsl:value-of select="concat(pos:translate('''') , trans-date)"/></LTAB>
<LTAB col=''18''><xsl:value-of select="pos:translate(''Temps:'')"/></LTAB>
<LTAB col=''23''><xsl:value-of select="concat(pos:translate('' ''), trans-time)"/></LTAB><BR/>
</HIGH>
<LTAB col=''1''><xsl:value-of select="pos:translate(''Caisse:'')"/></LTAB>
<LTAB col=''7''><xsl:value-of select="concat(pos:translate('' ''), till/code)"/></LTAB><BR/>
<BR/>
<CENTER><xsl:value-of select="$Acrelec_sepaator"/></CENTER>
<BR/>
<!-- TCPOS Version -->
<xsl:if test="FDM/SoftwareVersion">
<LTAB><xsl:value-of select="concat(pos:translate(''TCPOS version: ''),FDM/SoftwareVersion/TCPOS)"/></LTAB><BR/>
<LTAB><xsl:value-of select="concat(pos:translate(''FDM version: ''),FDM/SoftwareVersion/PluginFDMFrontend)"/></LTAB><BR/>
</xsl:if>
</xsl:when\>
<xsl:otherwise\>
</xsl:otherwise\>
</xsl:choose\>
</xsl:template\>
</xsl:stylesheet\>
WHERE ID='1'";
I've tried refractoring by double quotes and single quoting anything and everything but it's not working.
Related
When I am looping thru list of files and doing transformation on each file in a folder the effect of the transformation is as if it keeps transforming first file again and again. The transformation looked to be caching.
Here is the Code for transformation:
I am doing this inside WebAPI call.. in .NET framework 4.5.2 version . The ASP.NET page is calling the WebAPI.
I tried all different overloads and moving instancing transformation new out of loop on the top. I did not find any easy way of disabling the caching.
var d = new DirectoryInfo(strXMLFolder);
foreach (FileInfo file in d.GetFiles())
{
String strXSLTFile = strParamArr[2];
String xmlFile = file.Name;
//File.WriteAllBytes(strFile, transferObj.XSLTTemplateFileData);
XslCompiledTransform proc = new XslCompiledTransform();
proc.Load(strXSLTFolder + strXSLTFile);
proc.Transform(strXMLFolder + xmlFile, strXMLFolder + xmlFile + "-IntermediateXML.xml");
..................................
The XSLT file has following Code:
<data>
<xsl:for-each select="//QuantitativeResponseAssay/Setup/Elements/*/Name">
<row>
<PLA_file_name>
<xsl:value-of select="$vFileName"/>
</PLA_file_name>
<Analyst>
<xsl:value-of select="$vAnalyst"/>
</Analyst>
<xsl:choose>
<xsl:when test="position() = 1">
<Sample>Reference</Sample>
</xsl:when>
<xsl:when test="position() = 2">
<Sample>Sample 1</Sample>
</xsl:when>
<xsl:when test="position() = 3">
<Sample>Sample 2</Sample>
</xsl:when>
<xsl:when test="position() = 4">
<Sample>QC</Sample>
</xsl:when>
<xsl:otherwise>
<Sample>Error</Sample>
</xsl:otherwise>
</xsl:choose>
<Sample_Name>
<xsl:value-of select="."/>
</Sample_Name>
<Upper_Asymptote>
<xsl:value-of select="//StatisticTestResults/StatisticTestResult[TestName='AdditionalTestParameterEstimateUpperAsymptote'][./InvolvedAssayElements[Name=current()]]/Value"/>
</Upper_Asymptote>
<Dynamic_Range>
<xsl:value-of select="//StatisticTestResult[TestName='AdditionalTestParameterEstimateDynamicRange'][./InvolvedAssayElements[Name=current()]]/Value" />
</Dynamic_Range>
<Slope_Factor>
<xsl:value-of select="//StatisticTestResult[TestName='AdditionalTestParameterEstimateSlope'][./InvolvedAssayElements[Name=current()]]/Value"/>
</Slope_Factor>
<Regression_pvalue>
<xsl:if test="current() != 'Reference Standard'">
<xsl:value-of select="//QuantitativeResponseAssay/AssayResults/AssayResult/StatisticTestResults/StatisticTestResult[TestName='FTestRegression'][./InvolvedAssayElements[Name=current()]]/PValue" />
</xsl:if>
</Regression_pvalue>
<nonparallelism_pvalue>
<xsl:if test="current() != 'Reference Standard'">
<xsl:value-of select="//QuantitativeResponseAssay/AssayResults/AssayResult/StatisticTestResults/StatisticTestResult[TestName='FTestNonParallelism'][./InvolvedAssayElements[Name=current()]]/PValue" />
</xsl:if>
</nonparallelism_pvalue>
<LOF_pvalue>
<xsl:if test="current() != 'Reference Standard'">
<xsl:value-of select="//QuantitativeResponseAssay/AssayResults/AssayResult/StatisticTestResults/StatisticTestResult[TestName='FTestNonLinearity'][./InvolvedAssayElements[Name=current()]]/PValue" />
</xsl:if>
</LOF_pvalue>
<Potency>
<xsl:if test="string-length(//QuantitativeResponseAssay/AssayResults/AssayResult/PotencyResults/PotencyResult[TestControlSampleName=current()]/RelativePotencyValue) > 1">
<xsl:value-of select="//QuantitativeResponseAssay/AssayResults/AssayResult/PotencyResults/PotencyResult[TestControlSampleName=current()]/RelativePotencyValue * 100 " />
</xsl:if>
</Potency>
<!-- Column L Width_CI v -->
<Width_CI>
<xsl:if test="string-length(//QuantitativeResponseAssay/AssayResults/AssayResult/PotencyResults/PotencyResult[TestControlSampleName=current()]/PercentualRelativePotencyRange) > 1">
<xsl:value-of select="//QuantitativeResponseAssay/AssayResults/AssayResult/PotencyResults/PotencyResult[TestControlSampleName=current()]/PercentualRelativePotencyRange * 100 " />
</xsl:if>
</Width_CI>
<!-- Column M A_unrestricted v -->
<A_unrestricted>
<xsl:value-of select="//FullModel/FitResult/ParameterEstimate[ParameterName='A'][AssayElementName=current()]/Value" />
</A_unrestricted>
<!-- Column N B_unrestricted v -->
<B_unrestricted>
<xsl:value-of select="//FullModel/FitResult/ParameterEstimate[ParameterName='B'][AssayElementName=current()]/Value" />
</B_unrestricted>
<!-- Column O C_log2_unrestricted v -->
<C_unrestricted>
<xsl:value-of select="//FullModel/FitResult/ParameterEstimate[ParameterName='C'][AssayElementName=current()]/Value"/>
</C_unrestricted>
<!-- Column P D_unrestricted v -->
<D_unrestricted>
<xsl:value-of select="//FullModel/FitResult/ParameterEstimate[ParameterName='D'][AssayElementName=current()]/Value" />
</D_unrestricted>
<!-- Column Q G_unrestricted v -->
<G_unrestricted>
<xsl:value-of select="//FullModel/FitResult/ParameterEstimate[ParameterName='G'][AssayElementName=current()]/Value" />
</G_unrestricted>
<Template_ID>
<xsl:value-of select="$vTemplate"/>
</Template_ID>
<Template_Revision>
<xsl:value-of select="$vTemplateRevision"/>
</Template_Revision>
</row>
</xsl:for-each>
</data>
I expect different output in each intermediate.XML file but I keep getting the fist file result in the output in intermediate file.
I'm getting this error (Title) when trying to execute a Render using Fo.Net when creating a PDF.
[MethodImpl(MethodImplOptions.Synchronized)]
public static void MakePdf(XmlDocument xslFoDocument, Stream outputStream)
{
FonetDriver driver = PdfPrinterDriver.InitFonetDriver();
driver.Render(xslFoDocument, outputStream);
}
I found another post on this subject (for Java rather than for C# as I'm using but i assume it is the same error with the same cause): At least one of minimum, optimum, or maximum IPD must be specified on table - XSL-FO Apache FOP. The problem is that I can't find anywhere in the xsl file below where size hasn't been set. Anyone know what might be wrong? Below is the full XSL stylesheet file
EDIT: After further Troubleshooting I managed to localize the table causing the exception to be thrown. I still can't see where I've missed declaring the size though.
<fo:table-column column-width="7cm"/>
<xsl:for-each select="$units">
<xsl:variable name="bgcolor">
<xsl:choose>
<xsl:when test="position() mod 2 = 0">white</xsl:when>
<xsl:otherwise>#F4F2F0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<fo:table-column background-color="{$bgcolor}"/>
</xsl:for-each>
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block>
</fo:block>
</fo:table-cell>
<xsl:for-each select="$units">
<fo:table-cell text-align="center">
<xsl:choose>
<xsl:when test="not(contains($hiddenGroups, 'image'))">
<fo:block margin-top="3mm" margin-left="4mm" margin-right="4mm" margin-bottom="-0.8mm">
<fo:external-graphic content-width="500mm" width="100%" src="{$apiurl}ImageFiles/{Attributes/Attribute[#id='Image']/FileInfo/#id}/Data?apikey={$apikey}"/>
</fo:block>
<fo:block background-color="white" font-weight="600" padding-top="2mm" padding-bottom="2mm" margin-left="4mm" margin-right="4mm" margin-bottom="3mm">
<xsl:value-of select="#name"/>
</fo:block>
</xsl:when>
<xsl:otherwise>
<fo:block background-color="white" font-weight="600" padding-top="2mm" padding-bottom="2mm" margin-top="3mm" margin-left="4mm" margin-right="4mm" margin-bottom="3mm">
<xsl:value-of select="#name"/>
</fo:block>
</xsl:otherwise>
</xsl:choose>
</fo:table-cell>
</xsl:for-each>
</fo:table-row>
<xsl:for-each select="$general_attributes">
<xsl:variable name="attribute_id" select="#id"/>
<xsl:variable name="attribute_type" select="#attributeDefinitionType"/>
<xsl:if test="not(contains(#id, 'HIDE_COMP'))">
<fo:table-row keep-with-previous="always" border-bottom-style="solid" border-bottom-width="thin" border-bottom-color="#D0D0D0">
<fo:table-cell display-align="center" padding-top="2mm" padding-bottom="2mm">
<fo:block margin-left="2mm" margin-right="2mm">
<xsl:value-of select="#name"/>:
</fo:block>
</fo:table-cell>
<xsl:for-each select="$units">
<fo:table-cell padding-top="2mm" padding-bottom="2mm" padding-left="4mm" padding-right="4mm" display-align="center" border-left-style="solid" border-right-style="solid" border-width="0.1mm" border-color="#D0D0D0">
<xsl:call-template name="show-attribute">
<xsl:with-param name="type" select="$attribute_type"/>
<xsl:with-param name="attribute" select="Attributes/Attribute[#id=$attribute_id]"/>
<xsl:with-param name="count" select="count($units)"/>
</xsl:call-template>
</fo:table-cell>
</xsl:for-each>
</fo:table-row>
</xsl:if>
</xsl:for-each>
<xsl:if test="not(contains($hiddenGroups, 'Enkät'))">
<xsl:for-each select="$specific_attributes">
<xsl:variable name="attribute_id" select="#id"/>
<xsl:variable name="attribute_type" select="#attributeDefinitionType"/>
<xsl:if test="not(#group = preceding-sibling::*/#group)">
<fo:table-row>
<fo:table-cell padding-top="10mm" padding-bottom="5mm" number-columns-spanned="{1 + count($units)}">
<fo:block font-size="13" font-weight="bold" color="white" background-color="#0191ac" padding-top="2mm" padding-bottom="1.5mm" margin-bottom="2mm">
<fo:inline padding-left="4mm"><xsl:value-of select="#group"/></fo:inline>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:if>
<fo:table-row keep-with-previous="always" border-bottom-style="solid" border-bottom-width="thin" border-bottom-color="#D0D0D0">
<fo:table-cell display-align="center" padding-top="2mm" padding-bottom="2mm">
<fo:block margin-left="2mm" margin-right="2mm">
<xsl:value-of select="#name"/>
</fo:block>
</fo:table-cell>
<xsl:for-each select="$units">
<fo:table-cell padding-top="2mm" padding-bottom="2mm" padding-left="4mm" padding-right="4mm" display-align="center" border-left-style="solid" border-right-style="solid" border-width="0.1mm" border-color="#D0D0D0">
<xsl:call-template name="show-attribute">
<xsl:with-param name="type" select="$attribute_type"/>
<xsl:with-param name="attribute" select="Attributes/Attribute[#id=$attribute_id]"/>
<xsl:with-param name="count" select="count($units)"/>
</xsl:call-template>
</fo:table-cell>
</xsl:for-each>
</fo:table-row>
</xsl:for-each>
</xsl:if>
</fo:table-body>
</fo:table>
I'm marking this as answered and reference to the first comment from #lfurini. As for the last question #lfurini, I was looking at the wrong table when I thought I'd set the table width already. So to sum up for anyone else also wondering about this; If the width is set in fo:table, it's enough to set the width on one of the columns and the rest will adjust.
I have project used a xslt file to display records using below code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:param name="BasePath" select="/" />
<xsl:param name="OffersPerPage" select="4" />
<xsl:template match="/" xml:space="default">
<div class="offers_section">
<script>
$(document).ready(function() {
$(".offers_page").hide();
$("#OfferPage1").show();
});
function OffersPageChange(CurrentPage, NewPage)
{
$("#OfferPage" + CurrentPage).hide();
$("#OfferPage" + NewPage).show();
$("$offers_section").focus();
return false;
}
</script>
<xsl:choose>
<xsl:when test="count(//Offers/Offer) > 0">
<xsl:for-each select="//Offers/Offer[(position()) mod $OffersPerPage = 1 or position = 1]">
<xsl:variable name="page" select="position()" />
<xsl:variable name="lastpage" select="last()" />
<div class="offers_page"><xsl:attribute name="id">OfferPage<xsl:value-of select="$page" /></xsl:attribute>
<div class="offers_paging">
<xsl:if test="$page > 1">
<xsl:attribute name="onclick">return OffersPageChange(<xsl:value-of select="$page" />, <xsl:value-of select="$page - 1" />)</xsl:attribute>< Previous
</xsl:if>
<xsl:if test="$page < $lastpage">
<xsl:attribute name="onclick">return OffersPageChange(<xsl:value-of select="$page" />, <xsl:value-of select="$page + 1" />)</xsl:attribute>Next >
</xsl:if>
<br /><br />
<xsl:if test="$lastpage != 1">
<xsl:for-each select="//Offers/Offer">
<xsl:if test="(position() - 1) mod $OffersPerPage = 0">
<xsl:attribute name="class"><xsl:choose><xsl:when test="(position() - 1) div $OffersPerPage + 1 = $page">offers_page_number_active</xsl:when><xsl:otherwise>offers_page_number</xsl:otherwise></xsl:choose></xsl:attribute><xsl:attribute name="onclick">return OffersPageChange(<xsl:value-of select="$page" />, <xsl:value-of select="(position() - 1) div $OffersPerPage + 1" />)</xsl:attribute><xsl:value-of select="(position() - 1) div $OffersPerPage + 1" />
</xsl:if>
</xsl:for-each>
<br /><br />
</xsl:if>
</div>
<xsl:for-each select=". | following-sibling::Offer[(position()) < $OffersPerPage]" >
<div class="offers_offer">
<h2><xsl:value-of select="Partner" /></h2>
<xsl:if test="ImageSource != ''">
<div class="offers_image_container">
<div class="offers_image">
<img width="100%"><xsl:attribute name="src"><xsl:value-of select="$BasePath" />portals/7/<xsl:value-of select="ImageSource" /></xsl:attribute></img>
</div>
<div class="offers_image_overlay">
<img width="100%" height="33" alt=""><xsl:attribute name="src"><xsl:value-of select="$BasePath" />portals/_default/skins/onlyin/images/offer%20top%20swoop.png</xsl:attribute></img>
<img width="100%" height="126" style="position:absolute;bottom:0;left:0;right:0;" alt=""><xsl:attribute name="src"><xsl:value-of select="$BasePath" />portals/_default/skins/onlyin/images/offer%20bottom%20swoop.png</xsl:attribute></img>
</div>
</div>
</xsl:if>
<xsl:if test="Description != ''">
<div class="offers_description">
<xsl:value-of select="Description" /><br />
</div>
</xsl:if>
<xsl:if test="LegalInformation != '' and LegalOnOfferPage = 'True'">
<div class="offers_legal">
<xsl:value-of select="LegalInformation" /><br />
</div>
</xsl:if>
<xsl:if test="Facebook != '' or Twitter != ''">
<div class="offers_social_media">
Follow us on:<br />
<div class="social_media_links">
<xsl:if test="Facebook != ''">
<a class="facebook_logo" style="float:none;" target="_blank" title="Facebook"><xsl:attribute name="href"><xsl:value-of select="Facebook" /></xsl:attribute></a>
</xsl:if>
<xsl:if test="Twitter != ''">
<a class="twitter_logo" style="float:none;" target="_blank" title="Twitter"><xsl:attribute name="href">https://www.twitter.com/<xsl:value-of select="Twitter" /></xsl:attribute></a>
</xsl:if>
</div>
</div>
</xsl:if>
<xsl:if test="UrlText != ''">
<div class="offers_url">
<a target="_blank"><xsl:attribute name="onclick"><xsl:value-of select="onclick" /></xsl:attribute><xsl:attribute name="href"><xsl:value-of select="Url" /></xsl:attribute><xsl:value-of select="UrlText" /></a>
</div>
</xsl:if>
<xsl:if test="Email != ''">
<div class="offers_email">
Email: <a> <xsl:attribute name="onclick"><xsl:value-of select="Emailonclick" /></xsl:attribute><xsl:attribute name="href">mailto:<xsl:value-of select="Email" /></xsl:attribute><xsl:value-of select="Email" /></a>
</div>
</xsl:if>
<xsl:if test="Phone != ''">
<div class="offers_phone">
Tel no: <strong><xsl:value-of select="Phone" /></strong>
</div>
</xsl:if>
</div>
</xsl:for-each>
<xsl:if test="$lastpage > 1">
<div class="offers_paging">
<xsl:if test="$lastpage != 1">
<xsl:for-each select="//Offers/Offer">
<xsl:if test="(position() - 1) mod $OffersPerPage = 0">
<xsl:attribute name="class"><xsl:choose><xsl:when test="(position() - 1) div $OffersPerPage + 1 = $page">offers_page_number_active</xsl:when><xsl:otherwise>offers_page_number</xsl:otherwise></xsl:choose></xsl:attribute><xsl:attribute name="onclick">return OffersPageChange(<xsl:value-of select="$page" />, <xsl:value-of select="(position() - 1) div $OffersPerPage + 1" />)</xsl:attribute><xsl:value-of select="(position() - 1) div $OffersPerPage + 1" />
</xsl:if>
</xsl:for-each>
<br /><br />
</xsl:if>
<xsl:if test="$page > 1">
<xsl:attribute name="onclick">return OffersPageChange(<xsl:value-of select="$page" />, <xsl:value-of select="$page - 1" />)</xsl:attribute>< Previous
</xsl:if>
<xsl:if test="$page < $lastpage">
<xsl:attribute name="onclick">return OffersPageChange(<xsl:value-of select="$page" />, <xsl:value-of select="$page + 1" />)</xsl:attribute>Next >
</xsl:if>
</div>
</xsl:if>
</div>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<div class="offers_not_available">
Sorry, no offers are currently available in this category
</div>
</xsl:otherwise>
</xsl:choose>
</div>
Code behind code is:
void Load_Category(int CategoryId)
{
string skinPath = PortalSettings.ActiveTab.SkinPath;
XDocument XDocOffers = new XDocument(new XElement("Offers"));
SqlDataProvider provider = new SqlDataProvider();
SqlConnection SQLConnection = new SqlConnection(provider.ConnectionString);
SQLConnection.Open();
SqlConnection SQLConnectionAnswers = new SqlConnection(provider.ConnectionString);
SQLConnectionAnswers.Open();
SqlCommand sqlComm = new SqlCommand("OffersGetOffersByCategory", SQLConnection);
sqlComm.CommandType = CommandType.StoredProcedure;
sqlComm.Parameters.Add(new SqlParameter("#CategoryId", SqlDbType.Int)).Value = CategoryId;
SqlDataReader OffersReader = sqlComm.ExecuteReader();
string OfferId;
string Partner;
string Description;
string ImageSource;
string Url;
string UrlText;
string Email;
string Phone;
string LegalInformation;
string Facebook;
string Twitter;
string LegalOnOfferPage;
string onclick;
string Emailonclick;
while (OffersReader.Read())
{
OfferId = OffersReader["OfferId"].ToString();
Partner = OffersReader["Partner"].ToString();
Description = OffersReader["Description"].ToString();
ImageSource = OffersReader["ImageSource"].ToString();
Url = OffersReader["Url"].ToString();
UrlText = OffersReader["UrlText"].ToString();
Email = OffersReader["Email"].ToString();
Phone = OffersReader["Phone"].ToString();
LegalInformation = OffersReader["LegalInformation"].ToString();
Facebook = OffersReader["Facebook"].ToString();
Twitter = OffersReader["Twitter"].ToString();
LegalOnOfferPage = OffersReader["LegalOnOfferPage"].ToString();
onclick = "_gaq.push(['_trackEvent', 'Book Now', 'click', '" + Partner + "']);";
Emailonclick = "_gaq.push(['_trackEvent', 'Email', 'click', '" + Email + "']);";
XElement NextOffer =
new XElement("Offer",
new XElement("OfferId", OfferId),
new XElement("Partner", Partner),
new XElement("Description", Description),
new XElement("ImageSource", ImageSource),
new XElement("Url", Url),
new XElement("UrlText", UrlText),
new XElement("Email", Email),
new XElement("Phone", Phone),
new XElement("LegalInformation", LegalInformation),
new XElement("Facebook", Facebook),
new XElement("Twitter", Twitter),
new XElement("LegalOnOfferPage", LegalOnOfferPage),
new XElement("onclick", onclick),
new XElement("Emailonclick", Emailonclick)
);
XDocOffers.Element("Offers").Add(NextOffer);
}
OffersReader.Close();
SQLConnection.Close();
string XSLTFile = Server.MapPath(skinPath + "xslt/offers.xslt");
if (File.Exists(XSLTFile))
{
StringWriter XSLTOutput = new StringWriter();
XmlWriter XMLOutput = XmlWriter.Create(XSLTOutput);
// Load the style sheet.
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(XSLTFile);
XsltArgumentList ArgumentsQA = new XsltArgumentList();
if (Settings.ContainsKey("OffersPerPage"))
{
ArgumentsQA.AddParam("OffersPerPage", "", Settings["OffersPerPage"].ToString());
}
else
{
ArgumentsQA.AddParam("OffersPerPage", "", "4");
}
ArgumentsQA.AddParam("BasePath", "", "/");
// Execute the transform and output the results to a writer.
xslt.Transform(XDocOffers.CreateReader(), ArgumentsQA, XMLOutput);
//Output.Controls.Add(new LiteralControl(XSLTOutput.ToString().Replace("&", "&")));
Output.Controls.Add(new LiteralControl(HttpUtility.HtmlDecode(XSLTOutput.ToString())));
}
else
{
Output.Controls.Add(new LiteralControl("Cannot find XSLT file"));
}
}
Problem is:
Now display the detail in some different format for alternate row. currently, every offer has image in left side and description in right, for alternate row now i want to display description in left and image in right, i have never used xslt file before, can anyone please help... or suggest me how can achieve this.
waiting for your helpful answers..
i have solved out this problem..
Here is the solution, we didn't need to changes anything in c# code(code behind), we have just changed the xslt file t do this, as xslt file number of inbuilt functions to do.
I have used mod as below:
<xsl:for-each select=". | following-sibling::Offer[(position()) < $OffersPerPage]" >
<xsl:choose>
<xsl:when test="position() mod 2 = 1">
data 1
</xsl:when>
<xsl:otherwise>
data 2
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
That's all.....
My xslt transform does not pick up my document, this is because some/most elements are encoded,
e.g. my document:
<Template>
<ID>14</ID>
<Name>name of report</Name>
<VersionNumber>1.0</VersionNumber>
<CoverPage>
<br />
<br />
<h3 style="text-align: center;">
<br class="GENTICS_ephemera" />
</h3>
<h3 style="text-align: center;">
<br class="GENTICS_ephemera" />
</h3>
<h3 style="text-align: center;">Property Valuation Report</h3>
</CoverPage>
</Template>
This will never work:
<xsl:template match="span">
<fo:inline>
<xsl:call-template name="tokenize-style"/>
<xsl:apply-templates select="*|text()"/>
</fo:inline>
</xsl:template>
<xsl:template match="br">
<fo:block>
<fo:leader />
</fo:block>
</xsl:template>
Question: How can I get my document in the corrent format (technically my xml is valid and in correct format) but I want to do an xsl transform so I need to be able to pick up the correct tags
Here is the method for my transform:
private static MemoryStream Transform(XNode xmlData, XNode xslt)
{
XmlWriter writer = null;
var xslTrans = new XslCompiledTransform();
try
{
//load the xsl
xslTrans.Load(xslt.CreateReader());
//create the output stream
var result = new MemoryStream();
writer = XmlWriter.Create(result, null);
//create the xml reader for the data
var data = xmlData.CreateReader();
//do the actual transform of xml
xslTrans.Transform(data, null, writer);
writer.Close();
return new MemoryStream(result.ToArray());
}
catch (Exception e)
{
var errors = XslErrors.GetCompileErrors(xslTrans);
if (errors == null)
{
// Failed to obtain list of compile errors
throw;
}
if (writer != null) writer.Close();
throw e;
}
}
Update My XSLT Doc...
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" version="2.0"
xmlns:fp="http://example.com/fp"
exclude-result-prefixes="fp">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" />
<xsl:variable name="pagewidth" select="21.5"/>
<xsl:variable name="bodywidth" select="17"/>
<xsl:template match="Template">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family="Arial" font-size="9pt" color="black">
<fo:layout-master-set>
<fo:simple-page-master master-name="Cover" page-height="29.7cm" page-width="21cm" margin-top="2cm" margin-bottom="2cm" margin-left="2cm" margin-right="2cm">
<fo:region-body/>
</fo:simple-page-master>
<fo:simple-page-master master-name="BodyContent" page-height="29.7cm" page-width="21cm">
<fo:region-body margin-top="2cm" margin-bottom="2cm" margin-left="2cm" margin-right="2cm"/>
<!-- Header -->
<fo:region-before margin-bottom="2cm" extent="5cm" padding="0cm" border-width="0cm"/>
<!-- Footer -->
<fo:region-after margin-top="2cm" extent="2cm" padding="0cm" border-width="0cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="Cover">
<fo:flow flow-name="xsl-region-body" >
<fo:block id="CoverPageWrapper">
<xsl:apply-templates select="fp:ParseFragment(.)/node()"/>
<xsl:apply-templates select="CoverPage" />
</fo:block>
</fo:flow>
</fo:page-sequence>
<fo:page-sequence master-reference="BodyContent" initial-page-number="1">
<fo:static-content flow-name="xsl-region-before">
<fo:table margin-left="2cm" padding-top="1cm" table-layout="fixed" width="170mm">
<fo:table-column column-width="70mm" />
<fo:table-column column-width="100mm" />
<fo:table-body>
<fo:table-row>
<fo:table-cell padding-start="1pt" padding-end="1pt" padding-before="1pt" padding-after="1pt" padding-top="1pt" padding-bottom="1pt">
<fo:block-container width="3cm" height="2cm">
<fo:block>
</fo:block>
</fo:block-container>
</fo:table-cell>
<fo:table-cell padding-start="1pt" padding-end="1pt" padding-before="1pt" padding-after="1pt" padding-top="1pt" padding-bottom="1pt">
<fo:block-container width="4cm" height="2.2cm">
<fo:block>
</fo:block>
</fo:block-container>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:static-content>
<fo:static-content flow-name="xsl-region-after">
<fo:block text-align="center" font-size="8pt" padding-top="0.5cm">
Page
<fo:page-number/>
of
<fo:page-number-citation ref-id="FinalPage"/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<fo:block id="BodyContentWrapper">
<xsl:apply-templates select="Body" />
</fo:block>
<!-- End of the document stuff that is needed-->
<fo:block id="FinalPage"/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="label[#data-field-class='ui-templatefield']">
<xsl:choose>
<xsl:when test="#fo-checkbox" >
<xsl:choose>
<xsl:when test="text()='True'">
<fo:inline font-size="9pt" color="black">
[
<fo:inline font-family="ZapfDingbats" border-color="black" border-style="solid" border-width="1pt" font-size="6pt">✕</fo:inline>
]
</fo:inline>
</xsl:when>
<xsl:otherwise>
<fo:inline>
[ ]
<!-->fo:inline font-family="ZapfDingbats" font-size="10pt">❏</fo:inline-->
</fo:inline>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<fo:inline>
<xsl:apply-templates select="*|text()"/>
</fo:inline>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="span">
<fo:inline>
<xsl:call-template name="tokenize-style"/>
<xsl:apply-templates select="*|text()"/>
</fo:inline>
</xsl:template>
<xsl:template match="blockquote">
<fo:block
space-before="6pt" space-after="6pt"
start-indent="1em" end-indent="1em">
<xsl:apply-templates select="*|text()"/>
</fo:block>
</xsl:template>
<xsl:template match="h1">
<fo:block font-size="22pt">
<xsl:call-template name="tokenize-style"/>
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="h2">
<fo:block font-size="18pt">
<xsl:call-template name="tokenize-style"/>
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="h3">
<fo:block font-size="16pt">
<xsl:call-template name="tokenize-style"/>
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="h4">
<fo:block font-size="14pt">
<xsl:call-template name="tokenize-style"/>
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="h5">
<fo:block font-size="12pt" font-weight="bold">
<xsl:call-template name="tokenize-style"/>
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="h6">
<fo:block font-size="10pt" font-weight="bold">
<xsl:call-template name="tokenize-style"/>
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template name="tokenize-style">
<xsl:param name="pString" select="string(#style)"/>
<xsl:choose>
<xsl:when test="not($pString)"/>
<xsl:when test="contains($pString,';')">
<xsl:call-template name="tokenize-style">
<xsl:with-param name="pString"
select="substring-before($pString,';')"/>
</xsl:call-template>
<xsl:call-template name="tokenize-style">
<xsl:with-param name="pString"
select="substring-after($pString,';')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="{normalize-space(substring-before($pString,':'))}">
<xsl:value-of select="normalize-space(substring-after($pString,':'))"/>
</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="div">
<fo:block>
<xsl:if test="#class='bordered'">
<xsl:attribute name="border-width">1pt</xsl:attribute>
<xsl:attribute name="border-style">solid</xsl:attribute>
</xsl:if>
<xsl:call-template name="tokenize-style"/>
<xsl:apply-templates select="*|text()"/>
</fo:block>
</xsl:template>
<xsl:template match="p" >
<fo:block space-before="4pt" space-after="4pt">
<xsl:call-template name="tokenize-style"/>
<xsl:apply-templates select="*|text()"/>
</fo:block>
</xsl:template>
<xsl:template match="ol">
<fo:list-block start-indent="1cm" space-before="6pt" space-after="6pt">
<xsl:apply-templates/>
</fo:list-block>
</xsl:template>
<xsl:template match="ol/li">
<fo:list-item>
<fo:list-item-label end-indent="label-end()">
<fo:block>
<xsl:choose>
<xsl:when test="../#type != ''">
<xsl:number format="{../#type}"/>.
</xsl:when>
<xsl:otherwise>
<xsl:number format="1"/>.
</xsl:otherwise>
</xsl:choose>
</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="body-start()">
<fo:block font-size="11pt" color="black" font-family="Arial, Verdana, sans-serif">
<xsl:apply-templates/>
</fo:block>
</fo:list-item-body>
</fo:list-item>
</xsl:template>
<xsl:template match="ul">
<fo:list-block start-indent="1cm" space-before="6pt" space-after="6pt">
<xsl:apply-templates/>
</fo:list-block>
</xsl:template>
<xsl:template match="ul/li">
<fo:list-item>
<fo:list-item-label end-indent="label-end()">
<xsl:choose>
<xsl:when test="../#type ='disc'">
<fo:block>•</fo:block>
</xsl:when>
<xsl:when test="../#type='square'">
<fo:block font-family="ZapfDingbats">n</fo:block>
</xsl:when>
<xsl:when test="../#type='circle'">
<fo:block font-family="ZapfDingbats">m</fo:block>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="count(ancestor::ul) = 1">
<fo:block>•</fo:block>
</xsl:when>
<xsl:when test="count(ancestor::ul) = 2">
<fo:block font-family="ZapfDingbats">m</fo:block>
</xsl:when>
<xsl:otherwise>
<fo:block font-family="ZapfDingbats">n</fo:block>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</fo:list-item-label>
<fo:list-item-body start-indent="body-start()">
<fo:block>
<xsl:apply-templates/>
</fo:block>
</fo:list-item-body>
</fo:list-item>
</xsl:template>
<xsl:template match="dl">
<fo:block space-before="6pt" space-after="6pt">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="dt">
<fo:block>
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="dd">
<fo:block start-indent="5mm">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="table">
<fo:table>
<xsl:attribute name="width">
<xsl:text>170mm</xsl:text>
</xsl:attribute>
<xsl:apply-templates select="*|text()"/>
</fo:table>
</xsl:template>
<xsl:template match="caption">
<fo:caption>
<fo:block>
<xsl:apply-templates />
</fo:block>
</fo:caption>
</xsl:template>
<xsl:template match="colgroup">
<xsl:for-each select="col">
<fo:table-column>
<xsl:attribute name="column-width">
<xsl:choose>
<xsl:when test="contains(#width, '%')">
<xsl:value-of disable-output-escaping="yes" select="floor(number(translate(#width,'%','')) div 100 * $bodywidth)"/>
<xsl:text>cm</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of disable-output-escaping="yes" select="floor(#width div 72)"/>
<xsl:text>in</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</fo:table-column>
</xsl:for-each>
</xsl:template>
<xsl:template match="tbody">
<fo:table-body>
<xsl:apply-templates select="*|text()"/>
</fo:table-body>
</xsl:template>
<xsl:template match="tr">
<fo:table-row>
<xsl:apply-templates select="*|text()"/>
</fo:table-row>
</xsl:template>
<xsl:template match="th">
<fo:table-cell font-weight="bold" text-align="center">
<xsl:if test="ancestor::table/#border > 0">
<xsl:attribute name="border-style">solid</xsl:attribute>
<xsl:attribute name="border-width">0.1mm</xsl:attribute>
</xsl:if>
<fo:block>
<xsl:apply-templates select="*|text()"/>
</fo:block>
</fo:table-cell>
</xsl:template>
<xsl:template match="td">
<fo:table-cell padding-start="1pt" padding-end="1pt" padding-before="1pt" padding-after="1pt" padding-top="1pt" padding-bottom="1pt">
<xsl:if test="ancestor::table/#border > 0">
<xsl:attribute name="border-style">solid</xsl:attribute>
<xsl:attribute name="border-width">0.1mm</xsl:attribute>
</xsl:if>
<xsl:if test="ancestor::tr/#class='titleformat'">
<xsl:attribute name="background-color">black</xsl:attribute>
<xsl:attribute name="color">white</xsl:attribute>
<xsl:attribute name="font-size">9pt</xsl:attribute>
</xsl:if>
<fo:block>
<xsl:apply-templates select="*|text()"/>
</fo:block>
</fo:table-cell>
</xsl:template>
<xsl:template match="tt">
<fo:inline font-family="monospace">
<xsl:apply-templates select="*|text()"/>
</fo:inline>
</xsl:template>
<xsl:template match="img">
<fo:external-graphic>
<xsl:attribute name="src">
file:<xsl:value-of
select="#src"/>
</xsl:attribute>
<xsl:attribute name="width">
<xsl:value-of
select="#width"/>px
</xsl:attribute>
<xsl:attribute name="height">
<xsl:value-of
select="#height"/>px
</xsl:attribute>
</fo:external-graphic>
</xsl:template>
<xsl:template match="pre">
<fo:block white-space-collapse="false">
<xsl:apply-templates select="*|text()"/>
</fo:block>
</xsl:template>
<xsl:template match="b">
<fo:inline>
<xsl:attribute name="font-weight">bold</xsl:attribute>
<xsl:apply-templates select="*|text()"/>
</fo:inline>
</xsl:template>
<xsl:template match="i">
<fo:inline>
<xsl:attribute name="font-style">italic</xsl:attribute>
<xsl:apply-templates select="*|text()"/>
</fo:inline>
</xsl:template>
<xsl:template match="hr">
<xsl:if test="#class='ui-pagebreak'">
<fo:block break-after="page" />
</xsl:if>
<xsl:if test="#class=''">
<fo:block>
<fo:leader
leader-pattern="rule" leader-length.optimum="100%"
rule-style="double" rule-thickness="1pt"/>
</fo:block>
</xsl:if>
</xsl:template>
<xsl:template match="br">
<fo:block>
<fo:leader />
</fo:block>
</xsl:template>
</xsl:stylesheet>
Here is an example with XslCompiledTransform and an extension object:
class Program
{
static void Main(string[] args)
{
XslCompiledTransform proc = new XslCompiledTransform();
proc.Load("../../XSLTFile1.xslt");
XsltArgumentList xsltArgs = new XsltArgumentList();
xsltArgs.AddExtensionObject("http://example.com/fp", new FragmentParser());
proc.Transform("../../XMLFile1.xml", xsltArgs, Console.Out);
}
}
public class FragmentParser
{
public IXPathNavigable ParseFragment(string fragment)
{
XmlDocument doc = new XmlDocument();
XmlDocumentFragment frag = doc.CreateDocumentFragment();
frag.InnerXml = fragment;
return frag;
}
}
then in your stylesheet you can use code as the following:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fp="http://example.com/fp"
exclude-result-prefixes="fp"
>
<xsl:template match="CoverPage">
<Test>
<xsl:apply-templates select="fp:ParseFragment(.)/node()"/>
</Test>
</xsl:template>
<xsl:template match="h3">
<heading>
<xsl:apply-templates/>
</heading>
</xsl:template>
</xsl:stylesheet>
[edit]
In your stylesheet you can change
<fo:page-sequence master-reference="Cover">
<fo:flow flow-name="xsl-region-body" >
<fo:block id="CoverPageWrapper">
<xsl:apply-templates select="fp:ParseFragment(.)/node()"/>
<xsl:apply-templates select="CoverPage" />
</fo:block>
</fo:flow>
</fo:page-sequence>
to
<fo:page-sequence master-reference="Cover">
<fo:flow flow-name="xsl-region-body" >
<fo:block id="CoverPageWrapper">
<xsl:apply-templates select="fp:ParseFragment(CoverPage)/node()"/>
</fo:block>
</fo:flow>
</fo:page-sequence>
Or add a template for CoverPage e.g.
<xsl:template match="CoverPage">
<xsl:apply-templates select="fp:ParseFragment(.)/node()"/>
</xsl:template>
and then above you would simply do e.g.
<fo:page-sequence master-reference="Cover">
<fo:flow flow-name="xsl-region-body" >
<fo:block id="CoverPageWrapper">
<xsl:apply-templates select="CoverPage" />
</fo:block>
</fo:flow>
</fo:page-sequence>
Basically, I have a RichTextBox and I want to convert the formatted contents of it to HTML so it can be sent as an email.
The method I am currently using does not give any formatting at all:
string message = new TextRange(messageTextBox.Document.ContentStart,
messageTextBox.Document.ContentEnd).Text;
So I searched around and found this, however, it is over 5 years old and in the comments an MSFT user has commented saying that it is no longer supported - "This sample has been removed from our sample set and is no longer supported", and the HTML it generates is in an older format than modern HTML or XHTML which would be better to have.
Can anybody show me how I can convert the formatted contents of a RichTextBox to HTML?
(So when the email is sent it the recipient sees the email with formatting)
The general technique is to use a XamlWriter to convert the FlowDocument content to a stream of XML, and then to use an XSLT transform to convert the XML to HTML. That's not much of an answer, but that's because there's a huge range of possible HTML representations of any given FlowDocument.
This transform, for instance, converts every top-level Section to a div, every Paragraph to a p, and every Run to a span whose class tells you whether or not it's italicized, bold-faced, or underlined, or any combination of the above. It was useful for the purpose I wrote it for, but to call it a lossy transformation is an understatement:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl x">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="x:Section[not(parent::x:Section)]">
<div>
<xsl:apply-templates select="node()"/>
</div>
</xsl:template>
<xsl:template match="x:Section">
<xsl:apply-templates select="node()"/>
</xsl:template>
<xsl:template match="x:Paragraph">
<p>
<xsl:apply-templates select="node()"/>
</p>
</xsl:template>
<xsl:template match="x:Run">
<xsl:variable name="class">
<xsl:if test="#FontStyle='Italic'">
<xsl:text>i </xsl:text>
</xsl:if>
<xsl:if test="#FontWeight='Bold'">
<xsl:text>b </xsl:text>
</xsl:if>
<xsl:if test="contains(#TextDecorations, 'Underline')">
<xsl:text>u </xsl:text>
</xsl:if>
</xsl:variable>
<span>
<xsl:if test="normalize-space($class) != ''">
<xsl:attribute name="class">
<xsl:value-of select="normalize-space($class)"/>
</xsl:attribute>
</xsl:if>
<xsl:value-of select="text()"/>
</span>
</xsl:template>
</xsl:stylesheet>
Here's a value converter I wrote to do the conversion - note that in order to use the value converter, you also have to hack around and implement a version of RichTextBox that exposes the content as a dependency property. Really this whole project was a pain.
public class FlowDocumentToHtmlConverter : IValueConverter
{
private static XslCompiledTransform ToHtmlTransform;
private static XslCompiledTransform ToXamlTransform;
public FlowDocumentToHtmlConverter()
{
if (ToHtmlTransform == null)
{
ToHtmlTransform = LoadTransformResource("Converters/FlowDocumentToXhtml.xslt");
}
if (ToXamlTransform == null)
{
ToXamlTransform = LoadTransformResource("Converters/XhtmlToFlowDocument.xslt");
}
}
private static XslCompiledTransform LoadTransformResource(string path)
{
Uri uri = new Uri(path, UriKind.Relative);
XmlReader xr = XmlReader.Create(Application.GetResourceStream(uri).Stream);
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xr);
return xslt;
}
#region IValueConverter Members
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value is FlowDocument))
{
return null;
}
if (targetType == typeof(FlowDocument))
{
return value;
}
if (targetType != typeof(string))
{
throw new InvalidOperationException(
"FlowDocumentToHtmlConverter can only convert back from a FlowDocument to a string.");
}
FlowDocument d = (FlowDocument)value;
using (MemoryStream ms = new MemoryStream())
{
// write XAML out to a MemoryStream
TextRange tr = new TextRange(
d.ContentStart,
d.ContentEnd);
tr.Save(ms, DataFormats.Xaml);
ms.Seek(0, SeekOrigin.Begin);
// transform the contents of the MemoryStream to HTML
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
XmlWriterSettings xws = new XmlWriterSettings();
xws.OmitXmlDeclaration = true;
XmlReader xr = XmlReader.Create(ms);
XmlWriter xw = XmlWriter.Create(sw, xws);
ToHtmlTransform.Transform(xr, xw);
}
return sb.ToString();
}
}
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
{
return new FlowDocument();
}
if (value is FlowDocument)
{
return value;
}
if (targetType != typeof(FlowDocument))
{
throw new InvalidOperationException(
"FlowDocumentToHtmlConverter can only convert to a FlowDocument.");
}
if (!(value is string))
{
throw new InvalidOperationException(
"FlowDocumentToHtmlConverter can only convert from a string or FlowDocument.");
}
string s = (string)value;
FlowDocument d;
using (MemoryStream ms = new MemoryStream())
using (StringReader sr = new StringReader(s))
{
XmlWriterSettings xws = new XmlWriterSettings();
xws.OmitXmlDeclaration = true;
using (XmlReader xr = XmlReader.Create(sr))
using (XmlWriter xw = XmlWriter.Create(ms, xws))
{
ToXamlTransform.Transform(xr, xw);
}
ms.Seek(0, SeekOrigin.Begin);
d = XamlReader.Load(ms) as FlowDocument;
}
XamlWriter.Save(d, Console.Out);
return d;
}
#endregion
}
Extended version of XSLT sheet above I thought might help. Not perfect but slightly more comprehensive. Extension of an extension of another answer referencing this one.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl x">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<!--<xsl:template match="x:Section[not(parent::x:Section)]">
<div>
<xsl:apply-templates select="node()"/>
</div>
</xsl:template>-->
<xsl:template match="x:Section[not(parent::x:Section)]">
<xsl:variable name="style">
<xsl:if test="#FontStyle='Italic'">
<xsl:text>font-style:italic;</xsl:text>
</xsl:if>
<xsl:if test="#FontWeight='Bold'">
<xsl:text>font-weight:bold;</xsl:text>
</xsl:if>
<xsl:if test="contains(#TextDecorations, 'Underline')">
<xsl:text>text-decoration:underline;</xsl:text>
</xsl:if>
<xsl:if test="#FontSize != ''">
<xsl:text>font-size:</xsl:text>
<xsl:value-of select="#FontSize" />
<xsl:text>pt;</xsl:text>
</xsl:if>
<xsl:if test="#FontFamily != ''">
<xsl:text>font-family:</xsl:text>
<xsl:value-of select="#FontFamily" />
<xsl:text>;</xsl:text>
</xsl:if>
<xsl:if test="#Foreground != ''">
<xsl:text>color:</xsl:text>
<xsl:value-of select="concat(substring(#Foreground, 1, 1), substring(#Foreground, 4))" />
<xsl:text>;</xsl:text>
</xsl:if>
<xsl:if test="#Foreground-Color != ''">
<xsl:text>color:</xsl:text>
<xsl:value-of select="#Foreground-Color"/>
<xsl:text>;</xsl:text>
</xsl:if>
</xsl:variable>
<div>
<xsl:if test="normalize-space($style) != ''">
<xsl:attribute name="style">
<xsl:value-of select="normalize-space($style)"/>
</xsl:attribute>
</xsl:if>
<xsl:value-of select="text()"/>
<xsl:apply-templates select="node()"/>
</div>
</xsl:template>
<xsl:template match="x:Section">
<xsl:apply-templates select="node()"/>
</xsl:template>
<xsl:template match="x:Paragraph">
<xsl:variable name="style">
<xsl:if test="#FontStyle='Italic'">
<xsl:text>font-style:italic;</xsl:text>
</xsl:if>
<xsl:if test="#FontWeight='Bold'">
<xsl:text>font-weight:bold;</xsl:text>
</xsl:if>
<xsl:if test="contains(#TextDecorations, 'Underline')">
<xsl:text>text-decoration:underline;</xsl:text>
</xsl:if>
<xsl:if test="#FontSize != ''">
<xsl:text>font-size:</xsl:text>
<xsl:value-of select="#FontSize" />
<xsl:text>pt;</xsl:text>
</xsl:if>
<xsl:if test="#FontFamily != ''">
<xsl:text>font-family:</xsl:text>
<xsl:value-of select="#FontFamily" />
<xsl:text>;</xsl:text>
</xsl:if>
<xsl:if test="#Foreground != ''">
<xsl:text>color:</xsl:text>
<xsl:value-of select="concat(substring(#Foreground, 1, 1), substring(#Foreground, 4))" />
<xsl:text>;</xsl:text>
</xsl:if>
<xsl:if test="#Foreground-Color != ''">
<xsl:text>color:</xsl:text>
<xsl:value-of select="#Foreground-Color"/>
<xsl:text>;</xsl:text>
</xsl:if>
</xsl:variable>
<p>
<xsl:if test="normalize-space($style) != ''">
<xsl:attribute name="style">
<xsl:value-of select="normalize-space($style)"/>
</xsl:attribute>
</xsl:if>
<xsl:value-of select="text()"/>
<xsl:apply-templates select="node()"/>
</p>
</xsl:template>
<xsl:template match="x:Span">
<xsl:variable name="style">
<xsl:if test="#FontStyle='Italic'">
<xsl:text>font-style:italic;</xsl:text>
</xsl:if>
<xsl:if test="#FontWeight='Bold'">
<xsl:text>font-weight:bold;</xsl:text>
</xsl:if>
<xsl:if test="contains(#TextDecorations, 'Underline')">
<xsl:text>text-decoration:underline;</xsl:text>
</xsl:if>
<xsl:if test="#FontSize != ''">
<xsl:text>font-size:</xsl:text>
<xsl:value-of select="#FontSize" />
<xsl:text>pt;</xsl:text>
</xsl:if>
<xsl:if test="#FontFamily != ''">
<xsl:text>font-family:</xsl:text>
<xsl:value-of select="#FontFamily" />
<xsl:text>;</xsl:text>
</xsl:if>
<xsl:if test="#Foreground != ''">
<xsl:text>color:</xsl:text>
<xsl:value-of select="concat(substring(#Foreground, 1, 1), substring(#Foreground, 4))" />
<xsl:text>;</xsl:text>
</xsl:if>
<xsl:if test="#Foreground-Color != ''">
<xsl:text>color:</xsl:text>
<xsl:value-of select="#Foreground-Color"/>
<xsl:text>;</xsl:text>
</xsl:if>
</xsl:variable>
<span>
<xsl:if test="normalize-space($style) != ''">
<xsl:attribute name="style">
<xsl:value-of select="normalize-space($style)"/>
</xsl:attribute>
</xsl:if>
<xsl:value-of select="text()"/>
<xsl:apply-templates select="node()"/>
</span>
</xsl:template>
<xsl:template match="x:Run">
<xsl:variable name="style">
<xsl:if test="#FontStyle='Italic'">
<xsl:text>font-style:italic;</xsl:text>
</xsl:if>
<xsl:if test="#FontWeight='Bold'">
<xsl:text>font-weight:bold;</xsl:text>
</xsl:if>
<xsl:if test="contains(#TextDecorations, 'Underline')">
<xsl:text>text-decoration:underline;</xsl:text>
</xsl:if>
<xsl:if test="#FontSize != ''">
<xsl:text>font-size:</xsl:text>
<xsl:value-of select="#FontSize" />
<xsl:text>pt;</xsl:text>
</xsl:if>
<xsl:if test="#FontFamily != ''">
<xsl:text>font-family:</xsl:text>
<xsl:value-of select="#FontFamily" />
<xsl:text>;</xsl:text>
</xsl:if>
<xsl:if test="#Foreground != ''">
<xsl:text>color:</xsl:text>
<xsl:value-of select="concat(substring(#Foreground, 1, 1), substring(#Foreground, 4))" />
<xsl:text>;</xsl:text>
</xsl:if>
<xsl:if test="#Foreground-Color != ''">
<xsl:text>color:</xsl:text>
<xsl:value-of select="#Foreground-Color"/>
<xsl:text>;</xsl:text>
</xsl:if>
</xsl:variable>
<span>
<xsl:if test="normalize-space($style) != ''">
<xsl:attribute name="style">
<xsl:value-of select="normalize-space($style)"/>
</xsl:attribute>
</xsl:if>
<xsl:value-of select="text()"/>
<xsl:apply-templates select="node()"/>
</span>
</xsl:template>
</xsl:stylesheet>
For those who is looking for solution for .Net Core (APS.Net Core) - nuget MarkupConverter did the trick for me. Add dependency reference
<PackageReference Include="MarkupConverter" Version="1.0.6" />
Then use it
MarkupConverter.MarkupConverter markupConverter = new MarkupConverter.MarkupConverter();
try
{
message = markupConverter.ConvertXamlToHtml(message);
}
catch (Exception ex)
{
_logger.LogError(ex, $"Failed to parse flowdocument");
}