How to generate doctype declarations dynamically in XProc? - xproc

Requirement:
Is to add correct Doctype declaration on the output xml [The root element of the input xml can be chapter or section element]. For Instance, consider the chapter element public identifier is PUBLIC "-//OASIS//DTD DocBook Chap XML V4.5//EN" and system identifier is "chap.dtd". Simillary for section element public identifier is PUBLIC "-//OASIS//DTD DocBook Sec XML V4.5//EN" and system identifier is "sec.dtd".
Input XML1: chapter.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook Chap XML V4.5//EN" "chap.dtd">
<chapter>
<title>Chapter Template Title</title>
<para>Text</para>
<section>
<title>Section Title</title>
<para>Section text</para>
</section>
</chapter>
Input XML2: section.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook Chap XML V4.5//EN" "chap.dtd">
<section>
<title>Section Title</title>
<para>Section text</para>
</section>
XSLT file: test.xsl:
Stylesheet just copies input xml to output and adds #sec on all section elements
Stylesheet adds correct doctype declaration to output xml, because
the input xml root element can be or element
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template name="add-doctype-declaration">
<xsl:choose>
<xsl:when test="/chapter">
<xsl:text disable-output-escaping="yes">
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook Chap XML V4.5//EN" "chap.dtd">
</xsl:text>
</xsl:when>
<xsl:when test="/section">
<xsl:text disable-output-escaping="yes">
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook Sec XML V4.5//EN" "sec.dtd">
</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="/">
<xsl:call-template name="add-doctype-declaration"/>
<xsl:apply-templates/>
</xsl:template>
<!-- Identity Template -->
<xsl:template match="#*|*|processing-instruction()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="section">
<xsl:copy>
<xsl:apply-templates select="#*"/>
<xsl:attribute name="sec">
<xsl:number/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Expected output.xml for Input XML1
<?xml version="1.0" encoding="utf-8"?> Input XML1:
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook Chap XML V4.5//EN" "chap.dtd">
<chapter>
<title>Chapter Template Title</title>
<para>Text</para>
<section sec="1">
<title>Section Title</title>
<para>Section text</para>
</section>
</chapter>
Expected output.xml for Input XML2
<?xml version="1.0" encoding="utf-8"?> Input XML1:
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook Sec XML V4.5//EN" "sec.dtd">
<section sec="1">
<title>Section Title</title>
<para>Section text</para>
</section>
Using any XSLT engine, the transformation works absolutely fine, and able to get the expected output
But, if the transformation is done through XProc I end up with the following error. Can someone help in resolving this error
err:XD0001 : XD0001 It is a dynamic error if a non-XML resource is produced on a step output or arrives on a step input.
XProc file: test.xpl
<?xml version="1.0" encoding="UTF-8"?>
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc"
xmlns:c="http://www.w3.org/ns/xproc-step" version="1.0" name="testing">
<p:input port="source">
<p:document href="chapter.xml"/>
</p:input>
<p:output port="result">
<p:empty/>
</p:output>
<p:xslt version="1.0" name="transform">
<p:input port="stylesheet">
<p:document href="test.xsl"/>
</p:input>
<p:input port="parameters">
<p:empty/>
</p:input>
</p:xslt>
<!-- Assume that there is another transform happening for chapter/section xml -->
<p:xslt version="1.0" name="transform2">
<p:input port="stylesheet">
<p:document href="test2.xsl"/>
</p:input>
<p:input port="parameters">
<p:empty/>
</p:input>
</p:xslt>
<p:store omit-xml-declaration="false" encoding="utf-8" name="serialize">
<p:with-option name="href" select="output.xml"/>
</p:store>
</p:declare-step>

Again look at
Here is two simple examples that shows that you don't need to contextualize the Doctype generation
Section http://www.sharexml.com/x/get?k=uWn0KA7RThnt
Chapter http://www.sharexml.com/x/get?k=wAJlbUJfzIYQ
[UPDATED AFTER ANSWER]
And if you want that doctype change dynamically
Section http://www.sharexml.com/x/get?k=pBAwCds86RnQ
Chapter http://www.sharexml.com/x/get?k=JHEWghzgWIq1
Hope this helps

Related

How to get current date in xslt executed by XslCompiledTransform in .net core?

XslCompiledTransform is a xsl 1.0 processor, which doesn't support the current-dateTime() function. I've tried using my own script like this:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="urn:my-scripts"
exclude-result-prefixes="msxsl user">
<xsl:output method="xml" indent="yes"/>
<msxsl:script language="CSharp" implements-prefix="user">
public string current-dateTime()
{
return DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ssZ");
}
</msxsl:script>
<xsl:template match="...">
...
<xsl:value-of select="user:current-dateTime()"/></xsl:element>
...
</xsl:template>
</xsl:stylesheet>
And this works in .net framework, but not in .net core because it doesn't support scripts. How can I do this in .net core?

how to tokenize a paragraph in xslt

XML
<?xml version="1.0" encoding="UTF-8"?>
<!-- Edited by XMLSpy -->
<catalog>
<example>
:20:FT13261793408907
N23B:CRED
SA32A:130918USD111670,00
</example>
</catalog>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each select="catalog">
<tr>
<td><xsl:value-of select="example"> </td>
</tr>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Current OUTPUT
:20:FT13261793408907 N23B:CRED SA32A:130918USD111670,00
Desired OUTPUT
:20:FT13261793408907
N23B:CRED
SA32A:130918USD111670,00
output must not be in a same line its must be as shown in the desired o/p
A template match should do it;
$ cat catalog.xsl
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="catalog">
<xsl:value-of select="example"/>
</xsl:template>
</xsl:stylesheet>
$ xsltproc catalog.xsl catalog.xml
:20:FT13261793408907
N23B:CRED
SA32A:130918USD111670,00

openerp report with corporate header

i'm trying to make a report with corporate header but it doesn't work, the report is working fine but i don't have any corporate header, here is my code:
report.xml:
<report id="tracker_Labels"
model="noc.trajet"
name="noc.trajet"
string="Tracker Labels"
xml="module_coll/report/tracker_label.xml"
xsl="module_coll/report/tracker_label.xsl"
header="True"/>
tracker_label.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="../../base/report/corporate_defaults.xsl" />
<xsl:template match="/">
<xsl:call-template name="rml" />
</xsl:template> <!-- CONTENT -->
</xsl:stylesheet>
Regards,

XML Transform for ASP.Net TreeView Control

Not being an XML expert I'm struggling with this:
I need to populate an ASP.Net Treeview control from an XML dataSource. I can usually do this no problem except on this occasion the data I've been provided with is in this format:
<Staff>
<ID>1</ID>
<Name>Boss 1</Name>
<JobTitle>Top Boss</JobTitle>
<Staff>
<ID>2</ID>
<Name>Boss 2</Name>
<JobTitle>2nd Top Boss</JobTitle>
<Staff>
<ID>3</ID>
<Name>Boss 3</Name>
<JobTitle>3rd Top Boss</JobTitle>
<Staff>
<ID>4</ID>
<Name>Worker 1</Name>
<JobTitle>Worker</JobTitle>
</Staff>
</Staff>
</Staff>
</Staff>
and I need it to be like this for the treeview control:
<Staff ID="1" Name="Boss 1" JobTitle="Top Boss">
<Staff ID="2" Name="Boss 2" JobTitle="2nd Top Boss" >
<Staff ID="3" Name="Boss 3" JobTitle="3rd Top Boss" >
<Staff ID="4" Name="Worker 1" JobTitle="Worker" ></Staff>
</Staff>
</Staff>
</Staff>
I know this should be a doddle to do with an xsl file, but I'm failing miserably. My last attempt was:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="Staff">
<Staff>
<xsl:apply-templates/>
</Staff>
</xsl:template>
<xsl:template match="Staff">
<Staff>
<xsl:for-each select="*">
<xsl:attribute name="{name()}">
<xsl:value-of select="text()"/>
</xsl:attribute>
</xsl:for-each>
</Staff>
</xsl:template>
</xsl:stylesheet>
Any ideas?
Predictably I figured it out 30mins after posting. The following converts the xml above to the required format and appears to transform any xml elements to attibutes.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:template match="*">
<xsl:copy>
<xsl:for-each select="#*|*[not(* or #*)]">
<xsl:attribute name="{name(.)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates select="*[* or #*]|text()"/>
</xsl:copy>
</xsl:template>

Trying to use an XSLT for an XML in ASP.NET

i have the following xslt sheet:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:variable name="nhits" select="Answer[#nhits]"></xsl:variable>
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<div>
<xsl:call-template name="resultsnumbertemplate"/>
</div>
</xsl:template>
<xsl:template name="resultsnumbertemplate">
<xsl:value-of select="$nhits"/> matches found
</xsl:template>
</xsl:stylesheet>
And this is the xml that im trying to mix with the previous xslt:
<Answer xmlns="exa:com.exalead.search.v10" context="n%3Dsl-ocu%26q%3Dlavadoras" last="9" estimated="false" nmatches="219" nslices="0" nhits="219" start="0">
<time>
<Time interrupted="false" overall="32348" parse="0" spell="0" exec="1241" synthesis="15302" cats="14061" kwds="14061">
<sliceTimes>15272 </sliceTimes>
</Time>
</time>
</Answer>
Im using a xslcompiledtransform and that's working fine:
XslCompiledTransform transformer = new XslCompiledTransform();
transformer.Load(HttpContext.Current.Server.MapPath("xslt\\" + requestvariables["xslsheet"].ToString()));
transformer.Transform(xmlreader, null, writer);
My problems comes when im trying to put into a variable the "nhits" attribute value placed on the Answer element, but i'm not rendering anything using my xslt sheet.
Do you know what could be the cause?
Could be the xmlns attribute in my xml file?
Thanks in advance.
Best Regards.
Jose
Your immediate problem is that your XPath is wrong. Try
<xsl:variable name="nhits" select="/Answer/#nhits" />
However, I suggest a change to get rid of the variable altogether, you don't need it.
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output method="html" indent="yes"/>
<xsl:template match="Answer">
<div>
<xsl:value-of select="#nhits"/>
<xsl:text> matches found</xsl:text>
</div>
</xsl:template>
</xsl:stylesheet>
Your variable should be select="Answer/#nhits"
Your currect xpath of "Answer[#nhits]" tries to select Answer element that has an attribute named nhits..

Resources