'xslt transform from C#, failing when xsl refers to external files. How to get rid of dynamic external xsl:template
In visual C# I use a code to transform xml files into html. In XML notepad, I tested everything.
Problem here is, that the xsl has more than one file
ep-patent.xsl
cals2html.xsl
pat_com.xsl
pat_com_pre.xsl
tpl_com.xsl
label_de.xml
label_en.xml
label_fr.xml
Firstly, I had to remove DTD from the transformed file in order that the transform works, else it failed.
After many different combinations and errors, I figured out, I have to copy the files when compiling to the root, else it did not find the dependencies
copy "$(ProjectDir)xml_processing\label_de.xml" "$(TargetDir)label_de.xml"
copy "$(ProjectDir)xml_processing\label_en.xml" "$(TargetDir)label_en.xml"
copy "$(ProjectDir)xml_processing\label_fr.xml" "$(TargetDir)label_fr.xml"
copy "$(ProjectDir)xml_processing\cals2html.xsl" "$(TargetDir)cals2html.xsl"
copy "$(ProjectDir)xml_processing\ep-patent.xsl" "$(TargetDir)ep-patent.xsl"
copy "$(ProjectDir)xml_processing\pat_com.xsl" "$(TargetDir)pat_com.xsl"
copy "$(ProjectDir)xml_processing\pat_com_pre.xsl" "$(TargetDir)pat_com_pre.xsl"
copy "$(ProjectDir)xml_processing\tpl_com.xsl" "$(TargetDir)tpl_com.xsl"
Then I use a code similar to this:
XslCompiledTransform
using (XmlReader reader = XmlReader.Create(new StringReader(xsltString)))
{
var resolver = new XmlUrlResolver();
transform.Load(reader, sets, resolver);
}
using (XmlReader reader = XmlReader.Create(sreader))
{
transform.Transform(reader, null, results);
}
This combination ^^^^ worked fine. as soon as it is THE console app who runs Load and Transform.
But When Webapp from another project in the same Solution calls the same code, then "oh my god!!" again I get error complaining about absent external files because he looks up the dependencies in another weird directory. Namely, the root directory of WebSite (plus two levels up), not the root directory of Console app, which actually performs the job and loads the xsl file and has all of them within it's root.
I then tried to fiddle with current Directory this way:
var bundleAssembly = AppDomain.CurrentDomain.GetAssemblies().First(x => x.FullName.Contains("name of my console Project"));
var codebase = bundleAssembly.Location;
var MyDir = Directory.GetParent(codebase).FullName;
Directory.SetCurrentDirectory(MyDir);
When web page called the transform, before I touched the XSL transform, but it was not working.
So I had to make a further amendment
Regarding the files:
cals2html.xsl
pat_com.xsl
pat_com_pre.xsl
tpl_com.xsl
They where included like this
<!--include-->
<xsl:include href="tpl_com.xsl"/>
<xsl:include href="pat_com_pre.xsl"/>
<xsl:include href="pat_com.xsl"/>
<xsl:include href="cals2html.xsl"/>
So i copied contents and replaced it hard-way inside the root file. All works. This helped.
However with the 3 Language files, I still do not know how to incorporate them
label_de.xml
label_en.xml
label_fr.xml
My intent is, I want to get rid of multi-files layout since I am tired of so many combinations I have tested. Including changing current directory before calling the transform, but it id not help or I did it wrong.
I have some idea, to create hard-coded 3 templates one for each language
and then somehow I have to call
/lb[@name = $name]
at the specific template whose name I concat from $lang variable
but I am total beginner in this xsl world
Could someone help me build the new call....I'd welcome any hint. My goal is to include everything into single single one file, not having to ever go through the "where is the file" hell combinatoric game again.
Existing (bad) layout is:
tpl_com.xsl here i think he decides dynamically which one shall be called based on language
<xsl:template name="lib-label">
<xsl:param name="lang"/>
<xsl:param name="name"/>
<!--[debug]- ->
<br/>
lang = "<xsl:value-of select="$lang"/>"
<br/>
name = "<xsl:value-of select="$name"/>"
<br/>
<!- -[/debug]-->
<!--[src]-->
<xsl:value-of select="document(concat('label_', $lang, '.xml'))//lb[@name = $name]"/>
<!--[/src]-->
</xsl:template>
pat_com.xsl example of call
<xsl:call-template name="lib-label">
<xsl:with-param name="lang" select="$lang"/>
<xsl:with-param name="name" select="$name"/>
</xsl:call-template>
ep-patent.xsl example one-of-many calls
<xsl:call-template name="lib-label">
<xsl:with-param name="lang">
<xsl:value-of select="$lang"/>
</xsl:with-param>
<xsl:with-param name="name">Inid12B3seq</xsl:with-param>
</xsl:call-template>
label_en.xml How the individual files begin
<lbs lang="en" rq="spec +label">
label_fr.xml
<lbs lang="fr" rq="label">
<lbs lang="de" rq="spec">
The english one contains some rich elements:
<elt inid="15" xpath="/ep-patent-document/@correction-code" xpath2="B151" src="W1" dst="1 (W1">
<lb name="Inid15A">Correction information:</lb>
</elt>
<elt inid="15" xpath="/ep-patent-document/SDOBI/B100/B132EP" src="A2" dst="A2" rq="oriKind">
<lb name="Inid15B">Corrected version no</lb>
</elt>
<elt inid="15" rq="old-dtd B153 to specEPO B153EP" xpath="/ep-patent-document/SDOBI/B100/B150/B153EP" src="30" dst="30">
<lb name="AffInidTxt">INID code(s) </lb>
</elt>
While french and german contain simple ones like this:\
<lb name="Applic_B">Titulaire: </lb>
Do you think it is possible to include 3 lang files somehow by copy paste everything inside the main one without substantial re-working?
Or, how do you debug these things?
It is extremely time consuming black-box I have to test million of times to arrive at some progress.
Of course I first tested it by trying to remove all calls
<xsl:call-template name="lib-label">
and it helped, all worked, but of course, I did not have the labels then, in the resulting html documents.
Thank you
All the files are for download here: https://data.epo.org/publication-server/doc/ep-patent.xsl
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
