I have a problem. I think it is simple but I havent found it.
like below code I want to find and match multiplier factor value like "0.05" with "005" in the note value dynamically and take text "AAA" after "_ 005 _"(without spaces) and write it and others too.
I tried to use together both format number and concatenate to "concat(format-number(***))" but failed because of newby about this.
<cbc:Note>40.00 BT</cbc:Note>
<cbc:Note>17_ 2005.00</cbc:Note>
<cbc:Note>11_005_AAA</cbc:Note>
<cbc:Note>11_002_BBB</cbc:Note>
<cbc:Note>11_003_CCC</cbc:Note>
<cbc:InvoicedQuantity unitCode="CS">1.000</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="TRY">200.00</cbc:LineExtensionAmount>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:MultiplierFactorNumeric>0.03</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="TRY">6.00</cbc:Amount>
<cbc:BaseAmount currencyID="TRY">200.00</cbc:BaseAmount>
</cac:AllowanceCharge>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:MultiplierFactorNumeric>0.05</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="TRY">10.00</cbc:Amount>
<cbc:BaseAmount currencyID="TRY">200.00</cbc:BaseAmount>
</cac:AllowanceCharge>
current xslt block
<xsl:for-each select="./cac:AllowanceCharge/cbc:MultiplierFactorNumeric">
<br/>
<xsl:text> %</xsl:text>
<xsl:value-of select="format-number(. * 100, '###.##0,00', 'european')"/>,
</xsl:for-each>
I appreciate if you help me.
It is very difficult to understand your question.
The following minimal example is mostly based on a guess. It formats the MultiplierFactorNumeric value as a 3-digit whole number and uses it as a key to retrieve the corresponding Note value:
XML
<root>
<Note>40.00 BT</Note>
<Note>17_ 2005.00</Note>
<Note>11_005_AAA</Note>
<Note>11_002_BBB</Note>
<Note>11_003_CCC</Note>
<AllowanceCharge>
<MultiplierFactorNumeric>0.03</MultiplierFactorNumeric>
</AllowanceCharge>
<AllowanceCharge>
<MultiplierFactorNumeric>0.05</MultiplierFactorNumeric>
</AllowanceCharge>
</root>
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="note" match="Note" use="substring-before(substring-after(., '_'), '_')" />
<xsl:template match="/root">
<result>
<xsl:for-each select="AllowanceCharge">
<item>
<factor>
<xsl:value-of select="MultiplierFactorNumeric"/>
</factor>
<value>
<xsl:value-of select="substring-after(substring-after(key('note', format-number(100*MultiplierFactorNumeric, '000')), '_'), '_')"/>
</value>
</item>
</xsl:for-each>
</result>
</xsl:template>
</xsl:stylesheet>
Result
<?xml version="1.0" encoding="UTF-8"?>
<result>
<item>
<factor>0.03</factor>
<value>CCC</value>
</item>
<item>
<factor>0.05</factor>
<value>AAA</value>
</item>
</result>
I have the following xml file:
<?xml version="1.0" encoding="UTF-8"?>
<record
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"
xmlns="http://www.loc.gov/MARC21/slim">
....
<datafield tag="856" ind1=" " ind2=" ">
<subfield code="u">https://koha-test.pinoysystemslibrarian.info/cgi-bin/koha/opac-retrieve-file.pl?id=1362f36c9e3198f7ed369692140c4746</subfield>
</datafield>
....
And the following xslt:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE stylesheet>
<xsl:stylesheet version="1.0"
xmlns:marc="http://www.loc.gov/MARC21/slim"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings"
exclude-result-prefixes="marc str">
<xsl:import href="MARC21slimUtils.xsl"/>
<xsl:output method = "html" indent="yes" omit-xml-declaration = "yes" encoding="UTF-8"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="marc:record">
.... [Ommitted]
<xsl:choose>
<xsl:when test="$OPACEnableEbookReader='1'">
<xsl:attribute name="href">/ebookreader/?d=<xsl:value-of select="str:encode-uri(marc:subfield[#code='u'], true())"/>&ref=<xsl:value-of select="translate('$OPACBaseURL', '%2F', '/')"/>/cgi-bin/koha/opac-detail.pl?biblionumber=<xsl:value-of select="$biblionumber"/></xsl:attribute>
</xsl:when>
<xsl:otherwise>
What I wanted to do is that my xslt should convert HTML special characters like "/" and ":". I've tried translate to convert "%2F" which should be "/", which is in this line in my code:
<xsl:value-of select="translate('$OPACBaseURL', '%2F', '/')"/>
However, this is not being translated or converted. How do I go about this even though my output method is "html"? The OPACBaseURL is a variable which is a URL like so: https://example.com.
TIA!
This is very confusing.
If you have a string that contains %2F and you want to convert it to /, you need to use the str:decode-uri() function, not the translate() function - for example:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="str">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:variable name="myVar">abc%2Fdef</xsl:variable>
<xsl:template match="/">
<result>
<xsl:value-of select="str:decode-uri($myVar)"/>
</result>
</xsl:template>
</xsl:stylesheet>
returns:
<?xml version="1.0" encoding="UTF-8"?>
<result>abc/def</result>
Note also that the reference to the variable is not quoted.
So I have an XML file validated by its DTD and now I have to make transformations with an XSLT that should output all the each user's page to an XHTML file. I was told that I should use a 'for-each' but well, how can I do so that I get as an output one file for each user? (each output file should be an XHTML file with the information a user, in total one file per user)
XML (sample):
<store>
<users>
<user id="user1">
<name username="user1">User 1</name>
<email>user1#email.com</email>
<birth birth_date=""></birth>
<mob_number>123</mob_number>
<address>Street1</address>
<picture></picture>
<basket></basket>
</user>
<user id="user2">
<name username="user2">User 2</name>
<email>user2#email.com</email>
<birth birth_date=""></birth>
<mob_number>123</mob_number>
<address>Street1</address>
<picture></picture>
<basket></basket>
</user>
<user id="user3">
<name username="user3">User 3</name>
<email>user3#email.com</email>
<birth birth_date=""></birth>
<mob_number>123</mob_number>
<address>Street1</address>
<picture></picture>
<basket></basket>
</user>
<user id="user4">
<name username="user4">User 4</name>
<email>user4#email.com</email>
<birth birth_date=""></birth>
<mob_number>123</mob_number>
<address>Street1</address>
<picture></picture>
<basket></basket>
</user>
</users>
</store>
Thank you
As #MartinHonnen noted, xsl:result-document is the way to go.
This answer outputs each user as a separate file named HTML_userX:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:strip-space elements="*" />
<xsl:template match="/store/users">
<xsl:for-each select="user">
<xsl:result-document href="{concat('HTML_',#id)}" method="xhtml">
<xsl:copy-of select="." />
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
I'm writing an XSL transformer to convert XML to HTML. Here's my gun.xml:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="guns.xslt"?>
<guns xsi:noNamespaceSchemaLocation="guns2.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<gun>
<model>revolver</model>
<handy>1</handy>
<origin>Britain</origin>
<ttc>20mm</ttc>
</gun>
</guns>
And guns.xslt here:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/">
<html>
<body>
<h2>Gun Collection</h2>
<table border = "1">
<tr bgcolor = "#9acd32">
<th>Model</th>
<th>Origin</th>
<th>TTC</th>
</tr>
<xsl:for-each select="guns/gun">
<tr>
<td><xsl:value-of select = "model"/></td>
<td><xsl:value-of select = "handy"/></td>
<td><xsl:value-of select = "origin"/></td>
<td><xsl:value-of select = "ttc"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Both files are located in the same package, but XPAth doesn't recognize "guns/gun" in for-each block. What am I missing?
You have declared in xml-stylesheet - type as "text/xsl", please change file extension from "guns.xslt" to "guns.xsl" and also change in your XML as below:
<?xml-stylesheet type="text/xsl" href="guns.xsl"?>
Then your result will be as below:
I have an XML file as follows:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="test.xslt"?>
<results>
<test name="sentence1">
<description href="#ömr">
ömr1, ämr1, ümr1 and pär1
</description>
</test>
<test name="sentence2" href="#pär2">
<description>
ömr2, ämr2, ümr2 and pär2
</description>
</test>
<test name="sentence3" href="#pär3">
<description>
ömr3, ämr3, ümr3 and pär3
</description>
</test>
</results>
Then here is the XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:b="http://www.froglogic.com/XML2"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="html" version="5.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="Summary/test">
<html>
<body>
<xsl:for-each select="//test">
<xsl:variable name="linkMe" select="#name"/>
<xsl:value-of select="description"/>
<a href="#{$linkMe}" >
<xsl:value-of select="$linkMe" />
</a>
<xsl:value-of select="description"/>
</xsl:for-each>
</body>
</html>
</xsl:template>
I want to convert the XML to an HTML file using Perl. But it's going to have not desired output although I have told Perl I want output as a UTF-8.
The perl code is like this:
use strict;
use warnings;
use XML::LibXML;
use XML::Writer;
use XML::LibXSLT;
use XML::Parser;
use Encode qw( is_utf8 encode decode );
my $XML_File = "test2.xml";
my $XSLT_File = "test2.xslt";
my $HTML_File = "test2.html";
sub XML2HTML {
my $xml_parser = XML::LibXML->new('1.0', 'UTF-8');
my $xslt_parser = XML::LibXSLT->new('1.0', 'UTF-8');
my $xml = $xml_parser->parse_file($XML_File);
$xml->setEncoding('UTF-8');
my $xsl = $xml_parser->parse_file($XSLT_File);
my $stylesheet = $xslt_parser->parse_stylesheet($xsl);
my $results = $stylesheet->transform($xml);
my $output = $stylesheet->output_string($results);
$stylesheet->output_file($results, $HTML_File);
}
&XML2HTML($XML_File, $XSLT_File, $HTML_File);
Another question is how I could have UTF-8-BOM output as file? I searched the internet and could not find an exact answer. They all mention UTF-8 rather than UTF-8-BOM.
The HTML output seems unpleasant:
ömr1, ämr1, ümr1 and pär1 ömr2, ämr2, ümr2 and pär2 ömr3, ämr3, ümr3 and pär3
The encoding format in HTML is
Codepage 1252(Western)
and it is strange!
First, you have a subroutine which operates on global variables. That is not a good idea. Instead, those values as arguments to the function so your function is not tied to names you use in other places in your program.
Second, you do not do anything with $output, but storing the output in it will still increase the memory footprint of your program.
Third, looking at the underlying XS code for write_file, we see:
xsltSaveResultToFilename(filename, doc, self, 0);
And, xsltSaveResultToFilename is documented here. Looking at the source code for xsltSaveResultToFilename, we note that the routine deduces the output encoding from the stylesheet. So, the problem has to lie elsewhere.
It turns out, my initial diagnosis was incorrect. After getting my hands on a system with the necessary libraries, I ran your script (which revealed syntax errors in your XSL file -- don't post code we cannot run). After fixing those, I realized the code was producing UTF-8 encoded output, but the HTML did not include a declaration of document encoding. Therefore, when I viewed in my browser, it tried to use Windows 1252. Your XSL template needs to declare the encoding of the HTML document as well. Of course, if add the BOM, you probably don't need the declaration in the head of the document.
The following script seems to work for me:
use strict;
use warnings;
use autouse Carp => 'croak';
use File::BOM ();
use XML::LibXML;
use XML::LibXSLT;
xml_to_html('test.xml', 'test.xsl', 'test.html');
sub xml_to_html {
my ($xml_file, $xsl_file, $html_file) = #_;
open my $out, '>:unix', $html_file
or croak "Failed to open '$html_file': $!";
print $out $File::BOM::enc2bom{'UTF-8'}
or croak "Failed to write UTF-8 BOM: $!";
my $xslt_parser = XML::LibXSLT->new;
my $xml_parser = XML::LibXML->new;
my $xml = $xml_parser->parse_file( $xml_file );
my $xsl = $xml_parser->parse_file( $xsl_file );
my $style = $xslt_parser->parse_stylesheet( $xsl );
my $results = $style->transform( $xml );
$style->output_fh( $results, $out );
return;
}
with this template:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:b="http://www.froglogic.com/XML2"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="html" version="5.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>,
</head>
<body>
<xsl:for-each select="//test">
<xsl:variable name="linkMe" select="#name"/>
<xsl:value-of select="description"/>
<a href="#{$linkMe}" >
<xsl:value-of select="$linkMe" />
</a>
<xsl:value-of select="description"/>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
and produces the following output:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns:b="http://www.froglogic.com/XML2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">,
</head>
<body>
ömr1, ämr1, ümr1 and pär1
sentence1
ömr1, ämr1, ümr1 and pär1
ömr2, ämr2, ümr2 and pär2
sentence2
ömr2, ämr2, ümr2 and pär2
ömr3, ämr3, ümr3 and pär3
sentence3
ömr3, ämr3, ümr3 and pär3
</body>
</html>
I have
$ pacman -Ss libxslt
extra/libxslt 1.1.29+42+gac341cbd-1 [installed]
XML stylesheet transformation library
which does not seem to include support for generating HTML5 doctype.
Depending on your specific needs, you may have to tweak the XSLT file further.