1

from outside i'd like to pass a certain variable into an XSL (here no prob) and use it as an expression in the attribute "select" of a xsl:for-each element (the prob).

The following code (simplified, implemented in proper xml, stylesheet etc. elements) will NOT work, (but hopefully illustrates the task to do; injected is by example the string "books/book" assigned to param name searchstring)

...
<xsl:param name="searchstring" /> 

 <xsl:template match="/">
   <xsl:for-each select="$searchstring">
    <xsl:value-of select="title" />
   </xsl:for-each>
 </xsl:template>
...

because the "injected" param value is a string and will not bound to a result tree fragment, what is obviously expected by the "select" attribute. After a "full beard"-period of unsuccsessful research, I'd be very happy to find a way on ... how can this param value be turned into a fitting select expression?

best regards and thx already

1
  • Please post an example of the input and the expected output. Commented May 16, 2015 at 12:07

2 Answers 2

1

If you really need to pass in an XPath expression to be dynamically evaluated then you need XSLT 3.0 which has http://www.w3.org/TR/xslt-30/#element-evaluate or you need to check whether you preferred XSLT 1.0 or 2.0 processor offers an extension function like http://exslt.org/dyn/functions/evaluate/index.html. A different approach is to write a stylesheet that generates a second stylesheet, that way you can put your path parameter(s) in the place(s) you need them.

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

7 Comments

Thx for the quick response. It seems with regular XSLT1.0 -> no way out.
@BorisHoeller Not necesarily.
certainly I will try to work around e.g. using SimpleXML in the php script calling the xsl, but all the work in the xsl file turned kind of redundant, spreading sadness ;)
@BorisHoeller, regular XSLT 1.0 can certainly take the approach of having one stylesheet with path parameters create a second stylesheet with path expressions in the right place which can then be executed. And depending on (the lack of) the complexity of your path parameters there might be ways to break them up in XSLT 1.0 and select the nodes. But if you need to evaluate arbitrary path expression dynamically at runtime in a single stylesheet then you need an extension.
At this time, this summary: On the basis of pure XSLT1.0 in one file, without producing "secondary" XSL files, one is stuck. For me a good help, using my time for different solution to the problem from now on. Thx again!
|
0

If you are able to put some restrictions on the type of paths that will be passed as a parameter, then this can be done using a single XSLT 1.0 stylesheet.

It's too bad you refused to provide an example, forcing me to make up my own:

XSLT 1.0

<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:strip-space elements="*"/>

<xsl:param name="path"/>

<xsl:template match="/">
    <selected-nodes>
        <xsl:apply-templates/>
    </selected-nodes>
</xsl:template>

<xsl:template match="*">
    <xsl:variable name="path-to-me">
        <xsl:for-each select="ancestor-or-self::*">
            <xsl:value-of select="concat('/', name())"/>
        </xsl:for-each>    
    </xsl:variable>
    <xsl:if test="$path-to-me=$path">
        <xsl:copy-of select="."/>
    </xsl:if>
    <xsl:apply-templates select="*"/>
</xsl:template>

</xsl:stylesheet>

XML

<book>
    <chapter>
        <title>Chapter One</title>
        <section>
            <title>First Section</title>
                <subsection>
                    <title>Alpha</title>
                </subsection>
                <subsection>
                    <title>Bravo</title>
                </subsection>
                <subsection>
                    <title>Charlie</title>
                </subsection>
        </section>
        <section>
            <title>Second Section</title>
                <subsection>
                    <title>Delta</title>
                </subsection>
                <subsection>
                    <title>Echo</title>
                </subsection>
        </section>
    </chapter>      
    <chapter>
        <title>Chapter Two</title>
        <section>
            <title>Third Section</title>
                <subsection>
                    <title>Foxtrot</title>
                </subsection>
                <subsection>
                    <title>Golf</title>
                </subsection>
        </section>
        <section>
            <title>Fourth Section</title>
                <subsection>
                    <title>Hotel</title>
                </subsection>
                <subsection>
                    <title>India</title>
                </subsection>
                <subsection>
                    <title>Juliet</title>
                </subsection>
        </section>
    </chapter>      
</book>

Parameter

$path = "/book/chapter/section/title"

Result

<?xml version="1.0" encoding="UTF-8"?>
<selected-nodes>
   <title>First Section</title>
   <title>Second Section</title>
   <title>Third Section</title>
   <title>Fourth Section</title>
</selected-nodes>

Constraints:

  1. The parameter passed must be a full absolute path to an element (although the method could be expanded to include other node types);
  2. No predicates are allowed (although the method could be expanded to include numerical predicates);
  3. It is assumed that the source XML nodes are in no namespace.

1 Comment

thx a lot for this (I'm very sorry, I did not observe your request for code + your solution until now) - it looks like, the issue has been solved by you. Again thank you very much for this achievement!

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.