How can I capture current or active locale in DSpace XMLUI? - xslt-1.0

I have this setting in dspace.cfg webui.supported.locales = en, fr, zh. I wonder why I can't get the active or current locale if I use:
<xsl:value-of
select="/dri:document/dri:meta/dri:pageMeta/dri:metadata[#element='page'][#qualifier='currentLocale']"/>
in my item-view.xsl?
Viewing the page eg http://localhost:8080/DRI/handle/123456789/10476?locale-attribute=fr, it is obviously there in:
<metadata element="page" qualifier="currentLocale">fr</metadata>
Am I missing something?

Apparently, declaring this in a variable in the global-variables.xsl eg
<xsl:variable name="active-locale" select="/dri:document/dri:meta/dri:pageMeta/dri:metadata[#element='page'][#qualifier='currentLocale']"/>
solved my issue.
I can now capture the current/active locale. I still don't know why it won't work if I just use and declare the variable in item-view.xsl.

Related

Unable to set a null value when manipulating xml

I have the following xml:
<Company>
<Section>ABC</Section>
</Company>
I am conducting a negative test of sorts and want to send a NULL value to the "Section" element of the xml.
I tried the following:
* set xml /Company/Section = (null)
However, what happens is that the opening tag of the element gets deleted altogether resulting in:
<Company>
</Section>
</Company>
Expected result should be:
<Company>
<Section></Section>
</Company>
I would've liked to try .replace but the value inside "Section" is dynamic and so I cannot effectively use .replace. I also tried an empty string ('') and the same behavior happens where the opening tag gets deleted.
Please advise.
That is exactly what a null should do.
If an empty string does not work, that is a big surprise to me. Then the best option is you submit an issue and ideally contribute a PR to fix it also. Else consider what you ask for as not supported.

Default namespace of the xsl:document

I created originally the following variable:
<xsl:variable as="document-node()" name="changesTexts">
<xsl:document>
<ps >
<p>Processed with <ptr target="#{$applicationID}"/>.</p>
<p>proofreading according to workflow 1.1.</p>
</ps>
</xsl:document>
</xsl:variable>
When I tried to access it like this
<xsl:variable name="p" select="$changesTexts//p"/>
It didn't work: an empty item() was the result.
After I added the namespace to the root element,
<ps xmlns="http://www.music-encoding.org/ns/mei">
I can access the desired elements by:
<xsl:variable name="p" select="$changesTexts//mei:p"/>
So basically I solved my problem but I would like to understand how the things work. I couldn't figure out what kind of default namespace the elements in the first case get. I tried:
name() (BTW this doesn't show me the namespace in the regular xml document either)
namespace-uri()
Also, I noticed in the debugger, that the variable $changesTexts is of the type document-node and in other cases, when I use fn:document(), the variables are of the type document-node(1). So there is obviously some subtle difference (?)
When you use a literal result element S in XSLT to create an element R in your result tree, the expanded name of R will be the same as the expanded name of S: that is, it will have the same local-name and the same namespace.
So the namespace of the elements constructed by your <ps> and <p> instructions is determined by the default namespace declared in the stylesheet (probably on the xsl:stylesheet element, but it could be on some inner element).

Can I exclude a specific file name with Wix Heat using transforms?

Is it possible to exclude a specific file name with Wix using transforms?
I can exclude files that contain a certain string, but this excludes any file name matching the string. For example I can exclude file.exe with the following;
<xsl:key name="fileexe-search" match="wix:Component[contains(wix:File/#Source, 'file.exe')]" use="#Id"/>
but this will also exclude files with file.exe in their name, like file.exe.config.
Thanks.
Looks like you should use ends-with instead of contains. But ends-with does not exist in XSLT 1.0. :)
This answer gives enough details to get the idea of how to implement it. Basically it is a combination of substring and string-length functions.
Besides, you should also consider normalizing the casing before comparison. That is, it is better to lower-case (or upper-case) both strings - the original and the one it ends with. This post can give you an idea of how to do it.
Keeping all this in mind, you will end up with something similar to this:
<!-- The starting backslash is there to filter out files like 'abcfile.exe' -->
<!-- Besides, it's lower-cased to ease comparison -->
<xsl:variable name="FileName">\file.exe</xsl:variable>
<xsl:variable name="ABC">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
<xsl:variable name="abc">abcdefghijklmnopqrstuvwxyz</xsl:variable>
<xsl:key name="fileexe-search" match="wix:Component[translate(substring(wix:File/#Source, string-length(wix:File/#Source) - string-length($FileName) + 1), $ABC, $abc) = $FileName]" use="#Id"/>
Although the answer provided by #Yan works I prefer to use C# which is simpler to use.
<xsl:stylesheet version="1.0"
...
xmlns:my="urn:my-installer">
...
<msxsl:script language="C#" implements-prefix="my">
<msxsl:using namespace="System.IO" />
<![CDATA[
public bool EndsWith(string str, string end)
{
if (string.IsNullOrEmpty(str))
return false;
if (string.IsNullOrEmpty(end))
return false;
return str.EndsWith(end);
}
]]>
</msxsl:script>
...
Usage example:
<xsl:key name="ignored-components-search" match="wix:Component[my:EndsWith(wix:File/#Source, '.pssym')
or my:EndsWith(wix:File/#Source, '.pdb')
or my:EndsWith(wix:File/#Source, '.cs')
or my:EndsWith(wix:File/#Source,'.xml')
]" use="#Id" />

XSLT: Dynamic node name insertion based on template parameter

I am trying to generate the following structure in an XSLT template.
<ns:e1>
<child1>some value<child1>
<child2>some value<child2>
<child3>some value<child3>
</ns:e1>
or
<ns:e2>
<child1>some value<child1>
<child2>some value<child2>
<child3>some value<child3>
</ns:e2>
or other elements ns:e3 etc (although finite), based on a template parameter (say type). Typically I could use an xls:choose construct. In such a case, I would be duplicating the child elements (whose values are also template parameters).
Is there a way in XSLT to dynamically assume the element name ns:e1 or ns:e2 so that I can put the child elements once in its parent. I could save maintenance effort later if I have change the child elements or values (change once in one place and avoid bugs due to human errors).
Thanks for your help in advance.
Yes, you may use the xsl:element instruction to do that.
Assuming you always want to have <child1>some value<child1><child2>some value<child2><child3>some value<child3> as children for your parent element, you could rewrite your code like so:
<xsl:variable name="elementName">
<!-- compute the element name here ... -->
</xsl:variable>
<!-- Here we create an element having the name computed in variable elementName -->
<xsl:element name="{$elementName}" namespace="http://www.anamespace.com/and/so/on">
<child1>some value<child1>
<child2>some value<child2>
<child3>some value<child3>
</xsl:element>

xsl:template match not working

I have an image (in the content) with a src attribute
http://myPage/rss.gif
I wan't to change the attribute. The xsl:template match expression doesn't work..
<replace css:content="#content" css:theme=".content" />
<xsl:template match="img/#src[contains(., 'rss.gif')]">
<xsl:attribute name="src">/++theme++myPackage/images/<xsl:value-of select="." /></xsl:attribute>
</xsl:template>
What am I doing wrong?
In your example you select an img-tag containing the string rss.gif in its src-attribute, this string is probably http://myPage/rss.gif.
Then you add an attribute src to the img-tag beeing its value the concatenation of the strings /++theme++myPackage/images/ and the original value http://myPage/rss.gif.
The original value is added by <xsl:value-of select="." /></xsl:attribute>. This selects the whole value of the src-attribute!
Thus you get something like:
<img id="content" src="/++theme++myPackage/images/http://myPage/rss.gif" />
For test purposes you could first add an img-element whith the expected src-attribute to your theme.html file and check if the image file is accessed. Please check also that the value of src in your content file only contains the string that you want to append to /++theme++myPackage/images/.
BTW, in your example you replace the theme element by class: css:theme=".content". Remind that this will replace all elements with the class content. Consider using id or a narrower selector e.g. div.content or better div#someid.content.