Subject: Re: [xsl] Split into numbered files: without side-effect? (XSLT 2) From: Yves Forkl <Y.Forkl@xxxxxx> Date: Fri, 28 Sep 2007 15:32:13 +0200 |
XSLt has no way of evaluating a string as an XPath (in princiiple an xslt compiler may have parsed everything into internal form so the runtime system need not have any Xpath parser to hand at all. people
cooming from interpretted languages (or even compiled ones0 find
this strange, but it's no different from say, C, where you can't just
pass in a string of C syntax at run time and expect a compiled c
program to know whet to do with it unless it is linked to a C
compiler.
Very often though (eg sorting tables) you just need to specify an element name, not a full path and that can be done with
select="*[name()=$name]"
[etc.]
So if youi want to specify arbitrary paths [...] the way of doing it without an extension is to present teh xpaths as part of a stylesheet
that you import, so instead of a configuration file [...] You use
> If you've got XPath expressions stored in an XML document, then the > only way to evaluate them with standard XSLT is to generate a > stylesheet and then execute it.
That's exactly what I'm doing in some other project. Meta-stylesheets are a wonderful thing!
> It is not the only way. > > Someone (like me) may be able to parse an XPath expression using pure > XSLT (say for example with the FXSL LR Parsing Framework). Of course, > parsing is only half the way. The parsed expression need be > interpreted and this needs the context to be specified as well.
<xsl:param name="sorted_list_of_chunk_element_paths" as="node()*"> <xsl:for-each select="document('chunk_starting_elements.xml') /chunks/element"> <xsl:sort select="count(tokenize(., '/'))" order="descending"/> <xsl:sequence select="."/> </xsl:for-each> </xsl:param>
<xsl:function name="my:quote-for-regex"> <xsl:param name="input" as="xs:string"/> <xsl:sequence select="replace($input,'[\\\|\.\-\^\?\*\+\(\)\{\}\[\]\$]','\\$0')"/> </xsl:function>
<xsl:function name="my:xpath-of-element-node" as="xs:string"> <xsl:param name="element" as="node()"/> <xsl:value-of select="$element/ancestor-or-self::*/name()" separator="/"/> </xsl:function>
<xsl:function name="my:chunk-starter-path" as="node()*"> <xsl:param name="context-element" as="node()"/> <xsl:variable name="matching-path-nodes" as="node()*"> <xsl:for-each select="$sorted-list-of-chunk-element-paths"> <!-- anchor match at the beginning to avoid matching substrings of QNames --> <xsl:if test="matches(concat('#root/', my:xpath-of-element-node($context-element)), concat('^#root/([^/]+/)*', my:quote-for-regex(.), '$'))"> <xsl:sequence select="."/> </xsl:if> </xsl:for-each> </xsl:variable> <!-- select only the most specific path if several are found --> <xsl:sequence select="if (empty($matching-path-nodes)) then () else $matching-path-nodes[1]"/> </xsl:function>
<xsl:template match="*"> <xsl:if test="my:chunk-starter-path(.)"> <saxon:assign name="chunk-number" select="$chunk-number + 1"/> <xsl:result-document href="{concat('chunk_', format-number($chunk-number, '00'), '.txt')}"> <xsl:apply-templates/> </xsl:result-document> </xsl:if> <xsl:apply-templates/> </xsl:template>
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Split into numbered files, David Carlisle | Thread | Re: [xsl] Split into numbered files, David Carlisle |
RE: [xsl] Split into numbered files, Michael Kay | Date | Re: [xsl] Posting to XSL-List from , Steve |
Month |