Search

I have a situation where I need to load an unknown number of external .xml documents and access data from them.

a.xml
<data>
    <item handle="a1">a1</item>
    <item handle="a2">a2</item>
    <item handle="a3">a3</item>
    <item handle="a4">a4</item>
</data>

b.xml
<data>
    <item handle="b1">b1</item>
    <item handle="b2">b2</item>
    <item handle="b3">b3</item>
    <item handle="b4">b4</item>
</data>

xyz.xml
<data>
    <item handle="handle-of-bla">bla</item>
    <item handle="handle-of-xyz">xyz</item>
    <item handle="cute-handle">foo</item>
    <item handle="bar*2">bar</item>
</data>

My idea is to load these documents in a variable and access them from there:

<xsl:variable name="aux">
    <doc-a>
        <xsl:value-of select="document('a.xml')/data" />
    </doc-a>
    <doc-b>
        <xsl:value-of select="document('b.xml')/data" />
    </doc-b>
    <xsl:call-template name="add_more_docs" />
</xsl:variable>

<xsl:template name="add_more_docs">
    <doc-xyz>
        <xsl:value-of select="document('xyz.xml')/data" />
    </doc-xyz>
</xsl:template>

Usage would be like this:

<xsl:value-of select="$aux/item[ @handle='a1' ]" />

The problem is that I cannot access them like a node-set ... I tried to:

<xsl:variable name="ns_var" select="exsl:node-set($aux)" />

but without success.

Any ideas how can I add multiple node-sets to the same variable? Thanks.

My first guess would be to use copy-of instead of value-of in your nodeset-generating templates..

What does <xsl:copy-of select="$aux" /> yield?

I guess it shoud work with <xsl:value-of select="$aux/*/item[ @handle='a1' ]" /> or <xsl:value-of select="$aux/some-doc/item[ @handle='a1' ]" />.

@phoque

What does <xsl:copy-of select="$aux" /> yield?

<a>
    <data>
        <item handle="a1">a1</item>
        <item handle="a2">a2</item>
        <item handle="a3">a3</item>
        <item handle="a4">a4</item>
    </data>
</a>
<b>
<data>
        <item handle="b1">b1</item>
        <item handle="b2">b2</item>
        <item handle="b3">b3</item>
        <item handle="b4">b4</item>
</data>
</b>
<xyz xmlns:exsl="http://exslt.org/common">
    <data>
        <item handle="handle-of-bla">bla</item>
        <item handle="handle-of-xyz">xyz</item>
        <item handle="cute-handle">foo</item>
        <item handle="bar*2">bar</item>
    </data>
</xyz>

Solved. Wasn't looking at the markup of the result, but only to what browser outputs.

<xsl:value-of select="$aux/a/data/item[1]" />

Triggers an error

XSLTProcessor::transformToXml(): Invalid type
XSLTProcessor::transformToXml(): XPath evaluation returned no result.

XSLTProcessor::transformToXml(): runtime error: file file:[...]/pages/doc.xsl line 53 element value-of

But this works:

<xsl:value-of select="$ns_var/a/data/item[1]" />

outputs a1.

Thanks both for advices :)

Using <xsl:copy-of select="document('xyz.xml')/data" /> doesn't help?

Oh and I think

<xsl:variable name="ns_var" select="exsl:node-set($aux)" />

doesn't make much sense. $aux already is some XML. You make it accessible to xpath etc by using exsl:node-set(). But putting the result in another variable... You'd have to use exsl:node-set($ns_var) again to make that variable accessible to xpath.

@phoque

I edited the comment above. Solved it. It is interesting tough that I have to wrap $aux in exsl:node-set() to another variable.

Oh, you've fixed it in the meantime. :-)

In reply to your comment no.6, look at my comment (no.5), last part. It seems that I had to wrap it in exsl:node-set() to work ...

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details