[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

[xsl] Using multiple values stored in a variable


Subject: [xsl] Using multiple values stored in a variable
From: Manuel Souto Pico <m.soutopico@xxxxxxxxx>
Date: Sun, 6 Jan 2013 19:13:01 +0000

Hi there,

I've been stuck for a couple of days with a failing transformation, I
hope any one can help me out. Thank you very much in advance.

I have an external XML document that looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<glossary>
    <entry id="2">
        <source>
            <term>access</term>
        </source>
        <target>
            <term>acceso</term>
            <term>ingreso</term>
        </target>
    </entry>
</glossary>

That's a glossary that I use to proces the main XML document. I get it
like this:

<xsl:variable name="glossary" select=
            "document('file:////path/to/saxonhe9-3-0-11j/glossary.xml')"/>

For each entry in the glossary, I need to check whether ANY of the
terms (under target) is found in a string element of the main
document:

If there was only one term element under each target, it would be easy
to capture:

<xsl:variable name="target-term" select="../../target/term[normalize-space()]"/>

But since there might be any number of terms, I think I need to use
something like this (which seems to work):

<xsl:variable name="target-term" as="element()*"
select="../../target/term[normalize-space()]"/>

Then, for the actual check, this would work if there was only one
term, but if fails for the multiple valued variable that I have:

<xsl:when test="matches(string, $target-term, 'i')">
    <xsl:text>Found</xsl:text>
</xsl:when>

I get error XPTY0004: A sequence of more than one item is not allowed
as the second argument of
  matches() ("acceso", "ingreso")

The wrong bit should be the $target-term, but I don't know how to
write in order to check the mutiple values one by one.

Although I think I've given all the necessary details, the full
stylesheet is below if case you want to have a wider context or
improve anything (probably some of the recursions are unnecessary, and
the processing is slow):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
    exclude-result-prefixes="xd"
    version="2.0">
    <xsl:output method="text"/>

    <xsl:template match="/">

        <xsl:variable name="glossary" select=
            "document('file:////Users/souto/Tools/saxonhe9-3-0-11j/glossary.xml')"/>

        <xsl:for-each select="xliff//trans-unit/source">
            <xsl:variable name="source-segment" select="."/>
            <xsl:variable name="target-segment" select="../target"/>
            <xsl:for-each select="$glossary//source/term">
                <xsl:variable name="source-term" select="."/>
                <xsl:variable name="target-term" as="element()*"
select="../../target/term[normalize-space()]"/>
                <xsl:if test="matches($source-segment, $source-term, 'i')">
                    <xsl:choose>
                        <xsl:when test="matches($target-segment,
$target-term, 'i')">
                            <xsl:text>Term found.</xsl:text>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:text>Term not found.</xsl:text>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:if>
            </xsl:for-each>
        </xsl:for-each>

    </xsl:template>
</xsl:stylesheet>

Thanks a lot!

Cheers, Manuel


Current Thread
Keywords
xml