1

I have found several similar answers but I can't quite get why this is not working; This is a stripped down version of my real problem, but I have tested it and get the same result;

test1.xml

<?xml version="1.0" encoding="UTF8"?>
<fieldList>
<sourceField name="SourceTime">
<fid>REC_TIME</fid>
</sourceField>
</fieldList>

lookup.xml

<?xml version="1.0" encoding="UTF-8"?>
<data>
<field  name="REC_TIME" fid_type="DATE"/>
</data>

joinTest.xsml

<?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" encoding="UTF-8" media-type="text/plain"/>
<xsl:variable name="fieldDict" select="'lookup.xml'" />
<xsl:template match="/fieldList/*[fid]">
<xsl:variable name="id" select="current()"/>
<xsl:value-of select="$id"/>
<xsl:for-each select="document($fieldDict)/data/field[@name = $id]">
<xsl:value-of select="@type"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Now if I change the xpath to [@name] I get

REC_TIME
MONKEY

which is the result I want, but obviously the real file has much more than one entry so I need the filter to actually work!

I am testing this with xsltproc on Linux

xsltproc --version
Using libxml 20705, libxslt 10124 and libexslt 813
xsltproc was compiled against libxml 20632, libxslt 10124 and libexslt 813
libxslt 10124 was compiled against libxml 20632
libexslt 813 was compiled against libxml 20632

Many thanks.

3
  • Can you post the result you want to get? Commented Nov 5, 2010 at 13:06
  • Good question, +1. See my answer for a complete and short solution. :) Commented Nov 5, 2010 at 13:18
  • @Martin I sort of did, "REC_TIME MONKEY... which is what I would expect with the $id bit", it could be clearer, I'll edit it. Commented Nov 7, 2010 at 11:43

1 Answer 1

2

This transformation is the simplest correction of your XSLT code, that produces the wanted result:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my"
>
    <xsl:output method="xml" encoding="UTF-8" media-type="text/plain"/>

    <my:lookup>
        <data>
          <field  name="REC_TIME" fid_type="DATE"/>
        </data>
    </my:lookup>

    <xsl:variable name="fieldDict" select="document('')/*/my:lookup" />

    <xsl:template match="/fieldList/*[fid]">
        <xsl:variable name="id" select="fid"/>
        <xsl:value-of select="$id"/>
        <xsl:text> </xsl:text>
        <xsl:for-each select="$fieldDict/data/field[@name = $id]">
            <xsl:value-of select="@fid_type"/>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the provided XML document:

<fieldList>
    <sourceField name="SourceTime">
        <fid>REC_TIME</fid>
    </sourceField>
</fieldList>

the wanted result is produced:

REC_TIME DATE

Do note:

  1. The only significant change to your code was the definition of $id.

  2. Usually for such operations it is recommended to use keys in order to speedup processing.

Sign up to request clarification or add additional context in comments.

2 Comments

BOOOM! yes that worked. I'm curious as to why though. Is it because current() actually points to some other part of the document? When I print out the value using value-of, it looks the same as your version.
@Chris-Huang-Leaver: The string value of current() is the concatenation of all descendent text nodes -- this includes the white-space-only text nodes. Maybe using <xsl:strip-space elements="*"/> could help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.