I have an XSL file which uses a a static website link as shown below:
<xsl:template match="my_match">
<xsl:variable name="variable1">
<xsl:value-of select="sel1/Label = 'Variable1'"/>
</xsl:variable>
<xsl:copy-of select="sites:testPath('http://testsite.com/services/testService/v1.0', $fname, $lname,
$email , $zip, $phone, $comments, $jps, boolean($myvar), string(cust/@custID), string(@paID))"/>
</xsl:template>
My question is that how to read a properties file(key value pair) in the xsl file. so in my properties file (e.g. site.properties) I have a key called site
i.e. site=testsite.com/services/testService/v1.0
I want to use this site key in place of specifying url value in the xsl i.e. http://testsite.com/services/testService/v1.0. The reason for doing this is that this link changes depending on the various environments.
Is this possible? Please give your suggestions or a sample code if possible...Also if this is not possible...is there any work-around?
As a proof of concept:
Input .properties file:
# You are reading the ".properties" entry.
! The exclamation mark can also mark text as comments.
website = http://example.com
language = English
key\ with\ spaces = This is the value that could be looked up with the key "key with spaces".
Stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:f="Functions"
version="2.0">
<xsl:variable name="properties" select="unparsed-text('.properties')" as="xs:string"/>
<xsl:template match="/" name="main">
<xsl:value-of select="f:getProperty('language')"/>
</xsl:template>
<xsl:function name="f:getProperty" as="xs:string?">
<xsl:param name="key" as="xs:string"/>
<xsl:variable name="lines" as="xs:string*" select="
for $x in
for $i in tokenize($properties, '\n')[matches(., '^[^!#]')] return
tokenize($i, '=')
return translate(normalize-space($x), '\', '')"/>
<xsl:sequence select="$lines[index-of($lines, $key)+1]"/>
</xsl:function>
</xsl:stylesheet>
The f:getProperty('language')
will return 'English'.
See this as a proof of concept, this needs to be improved in many ways since it does not handle many of the different ways a .properties file can be authored.
I belive Alejandro or Dimitrie probably could improve this many times.
For an XSLT 1.0 solution, you could use an external (parsed) general entity in an XML file that will load the properties file as part of the XML content.
For example, if you had a properties file like this, named site.properties
:
foo=x
site=http://testsite.com/services/testService/v1.0
bar=y
You could create a simple XML file, named properties.xml
that "wraps" the content of the properties file and loads it using an external parsed general entity:
<!DOCTYPE properties [
<!ENTITY props SYSTEM "site.properties">
]>
<properties>
&props;
</properties>
Then, within your XSLT you can load that properties.xml
using the document()
function and obtain the value for a given key:
<?xml version="1.0" encoding="UTF-8"?>
<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:variable name="props" select="document('properties.xml')" />
<xsl:template match="/">
<output>
<example1>
<!--simple one-liner -->
<xsl:value-of select="substring-before(
substring-after($props,
concat('site','=')),
'
')" />
</example1>
<example2>
<!--using a template to retrieve the value
of the "site" property -->
<xsl:call-template name="getProperty">
<xsl:with-param name="propertiesFile" select="$props"/>
<xsl:with-param name="key" select="'site'"/>
</xsl:call-template>
</example2>
<example3>
<!--Another example using the template to retrieve
the value of the "foo" property,
leveraging default param value for properties -->
<xsl:call-template name="getProperty">
<!--default $propertiesFile defined in the template,
so no need to specify -->
<xsl:with-param name="key" select="'foo'"/>
</xsl:call-template>
</example3>
</output>
</xsl:template>
<!--Retrieve a property from a properties file by specifying the key -->
<xsl:template name="getProperty">
<xsl:param name="propertiesFile" select="$props"/>
<xsl:param name="key" />
<xsl:value-of select="substring-before(
substring-after($propertiesFile,
concat($key,'=')),
'
')" />
</xsl:template>
</xsl:stylesheet>
When applied to any XML input the stylesheet above will produce the following output:
<?xml version="1.0" encoding="UTF-8"?>
<output>
<example1>http://testsite.com/services/testService/v1.0</example1>
<example2>http://testsite.com/services/testService/v1.0</example2>
<example3>x</example3>
</output>
Note: this strategy will only work if the content of the properties file is "XML safe". If it were to contain characters, like &
or <
it would result in an XML parsing error when the properties.xml
file is loaded.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With