基于动态字符串的XPATH语句评估

时间:2015-03-06 01:09:42

标签: xslt xpath saxon

(排序)短和(可能?)甜蜜

如何将条件逻辑(与<xsl:if>'s test属性相同的XPATH)放入通过document('layoutsheet.xml')读取的XML工作表的属性中,而不使用任何一个saxon:evaluate或XSLT 3 <xsl:evaluate>实际评估调用XSL表中的逻辑? (dyn:evaluate似乎也出来了)


澄清:我最常寻找的是,如果有一些模式使用逻辑和相关变换的节点表示,这将使我有类似的行为。我不介意在XML表单中创建处理布局行为的代表性结构。我现在只是画了一个空白的东西,它不会演变成在XSL中写一个完整的解释器,这似乎可能是一种可怕的重复工作和浪费时间来获得低劣的结果。

因为我自己并没有调用XSL解析器(它是由软件调用的,我不会维护而且不能直接改变),所以我基本上只限于什么&&。 #39;萨克森人。我主要希望得到一个便携式答案,既可以用于我们自己未来的安全性,也可以用于潜在的共享,如果它在其他地方被证明具有任何价值。如果这是我最好用手头的工具管理的话,我听到这个就好了。


理想情况下,我希望将这种逻辑完全封装在XML表中,而不是依赖于在XSL表中了解它的特定方面。也就是说,我不想假设这将始终是使用特定函数调用来评估单个元素与值的两部分比较(例如,将逻辑评估的两侧存储为单独的属性,然后我会必须要知道在XSL表中相互评估是不理想的)。我也不想根据特定的布局结构制作匹配选择逻辑:我们的想法是使其尽可能与结构无关,而是在XML表格中包含相关的结构逻辑。

虽然我可以加载具有更深层结构的XML表作为匹配条件(当匹配评估为真时,或者其他情况下,它们会更深入地继续其身份转换结构),我理想情况下仍然会更喜欢灵活的东西更复杂的条件逻辑,而不仅仅是一个简单的两个值相等测试,例如完整的XPATH语句所允许的。


更长的解释和相关的代码片段

我在基于XSLT的CMS中工作,并尝试使用单独的XML工作表创建动态版本目标系统,以确定文档布局。到目前为止,这已经做了一些工作,但它很顺利。总而言之,我们需要更多的运行时动态而不是通过导入/包含嵌套简单地覆盖。

原始系统依赖于命名模板调用来拉入页面的不同区域,然后进行身份转换以完成包括相关部分。我基本上用一个使用命名空间模板&#34;调用&#34;的XML布局表替换了它。在我的XSL表格中匹配。这是一个初始迭代,旨在尽可能快地实现,同时提供深入的未来灵活性,因此保持接近于命名的调用范例。

我遇到的一个问题是如何处理条件展示位置而无需进行特定匹配和相应的&#34;调用&#34;并将相关逻辑附加到我的XSL表中,而不是将该逻辑模块化为XML。

我找到了一个使用saxon的当前工作解决方案:评估,但希望其他解决方案(XSLT 2)上的任何输入都不依赖于特定于供应商的扩展。因为这是在第三方CMS(OmniUpdate的OU校园)内,所以我自己无法加载扩展程序:我基本上已经陷入了Saxon已经加载的任何内容。

基本布局表:(带有XHTML的XML用于定义文档结构,然后通过XSLT从包含实际文档内容的调用XML文档表合并到其中)

<mus:layoutsheet org="msu" version="2"
xmlns:mus="http://www.montana.edu/web/xsl/variables"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ou="http://omniupdate.com/XSL/Variables"
exclude-result-prefixes="xsl mus ou">

    <mus:call-template name="pre-processing-pub" />     
    <mus:call-template name="doctype" />
    <html>

        <mus:call-template name="pre-processing"/>

        <mus:call-template name="head" />
        <body class="responsive">
            <mus:call-template name="header" />

            <div class="container">
                <div class="row">
                    <mus:call-template name="titles-region" />
                    <mus:call-template name="breadcrumb" />
                </div>
            </div>

            <div class="container" id="content">

                <!-- this is the full width feature region -->
                <mus:call-template name="banners-region" cond="ou:pcfparam('full-width-feature-area') = 'show'"/>
                <!-- ok how do we do conditional placement? because this needs to get called in here or in content -->
                <!-- how about having that as an attribute here, then we can react to that in the match-->

                <div class="row">

                    <mus:call-template name="nested-nav" />
                    <!--wrap in an if statement for handling the different locations when tabbed -->                        
                    <div id="rightpane" class="col-xs-12 pull-right page-content sec">
                        <mus:call-template name="banners-region" cond="not(ou:pcfparam('full-width-feature-area') = 'show')"/>

                        <mus:call-template name="content" />


                    </div>                          

                    <mus:call-template name="contact-info" /> 

                </div>
            </div>
            <!--<xsl:call-template name="bottom-span-bar" />    -->

            <mus:call-template name="footer" />
        </body>
    </html>
</mus:layoutsheet>

相关元素包括<mus:call-template name="banners-region" cond="ou:pcfparam('full-width-feature-area') = 'show'"/><mus:call-template name="banners-region" cond="not(ou:pcfparam('full-width-feature-area') = 'show')"/>

@cond是使用XPATH语句加载的属性,否则它将是围绕此模板的xsl:if测试的内容&#34; call&#34;在每种情况下。

请注意,虽然这个版本的Saxon确实有可用的XSLT 3元素,包括<xsl:evaluate>,但在使用函数调用{{1}时尝试使其工作时,我一直在遇到名称空间问题(所有正确的命名空间都包含在调用xsl表中,所以不是这样)。虽然我可以取消函数调用并使用纯xpath,但我必须使用//来避免与部分相关元素结构的另一个命名空间问题,而且现在它也已经破坏了(可能是因为它引用调用转换过程的xml工作表中的元素,而不是存储布局的xml工作表。我还希望尽可能避免使用XSLT 3,暂时保留一些我可以使用的基本方法。

相关匹配模板:

ou:pcfparam

我觉得也许我在这里忽略了一些东西,可能是一些本来应该是显而易见的东西(也许是因为我正试图不让支气管炎,等等)。虽然saxon:evaluate对我来说简单易用,但我更喜欢更便携的东西,因为这种方法通常允许沿着MVC架构概念进行一些非常好的模块化,以便使用相对简单的方式处理非结构化的基于XML的内容表XHTML + light XML布局表处理大部分视图结构和表示,使不熟悉XSLT的人更容易修改相关结构。

注意: EXSLT的dyn:评估没有在Saxon中实现,因此它不是交叉兼容的选项,尽管如果它在功能上等同于我想我可以坚持撒克逊:评估并告诉人们用dyn替换它:如果没有在撒克逊上进行评估,这可能是最好的方式。


实际调用XML表的格式的缩写示例(我减少了元素的数量,但结构是相同的,它本质上是一个选项和相关的内容表,并且是CMS内的编辑器实际上保存了更改):

<xsl:template match="mus:call-template[@name='banners-region']">
    <xsl:if test="saxon:evaluate(@cond)">
        <xsl:call-template name="slider" /> 
    </xsl:if>
</xsl:template>

2 个答案:

答案 0 :(得分:3)

两个建议

  1. 直接编写XSLT。需要动态评估XPath 表达式是你遇到复杂问题的一个标志。继续前进 不建议敲打。
  2. 或者,如果你真的必须发明自己的基于XML的模板语言,那么 编写XSLT将XML模板转换为XSLT,然后 直接执行这个生成的XSLT。以XSLT为目标 语言,你将拥有它的全部力量(包括XPath表达式 您可以动态调用的评估) 无需依赖特定于处理器的扩展。

答案 1 :(得分:2)

我会认真看看@kjhughes的第二个建议。我没有真正关注你的问题描述,但在我看来,你正在设计一种微型转换语言来操纵你的内容,我发现当你发现自己这样做时,将你的语言翻译成XSLT然后运行生成的XSLT通常比使用XSLT编写的解释器解释语言并调用xsl:evaluate来评估路径表达式更容易(也更快,更便携),这实际上就是你当前正在做的事情。

使用Orbeon或Calabash等管道处理器可以帮助管理整体控制流程。