【问题标题】:Template match nodes that have a particular child node - streaming XSLT具有特定子节点的模板匹配节点 - 流式 XSLT
【发布时间】:2017-12-07 12:21:48
【问题描述】:

我想选择在 Addl_Information 部分中出现 Plan 子节点的 Worker 节点

<xsl:mode streamable="yes"/>
<xsl:template match="Worker[Addl_Information/Plan]">

当我使用上述代码时,我收到来自 Saxon-EE 9.6.0.5 处理器的错误提示

XTSE3430: Template rule is declared streamable but it does not satisfy the streamability rules. * The match pattern is not motionless

我做错了什么?

我在w3c site 中看到了(类似)静止模式的示例,但它对我不起作用,请指教。

更新:这是我的样式表。我试图只包括在他们的工人数据中记录了某个计划的人。请注意,下面的patth 变量是我试图评估的另一个角度 - 基本上在剩余代码周围有一个 IF 条件。这也行不通。

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:mode streamable="yes"/>
        <xsl:template match="Worker_Sync">
            <File>
                <xsl:apply-templates select="Worker"/>    
            </File>
        </xsl:template>

        <xsl:template match="Worker">
            <xsl:variable name="ThisPerson" select="copy-of()"/> 
            <xsl:variable name="patth" select="Additional_Information/ws:plan"/>
            <xsl:if test="$ThisPerson/$patth">
                <Row>
                    <A1_Account_Number><xsl:value-of select="$ThisPerson/Additional_Information/Account_Number"/></A1_Account_Number>
                    <A2_Employee_Number>...</A2_Employee_Number>
                </Row>
            </xsl:if>
        </xsl:template>
    </xsl:stylesheet>

【问题讨论】:

  • 您的模式类似于p[b],其中规范说“谓词不是静止的”。
  • 嗯,我想我开始掌握这种语言了。第一次制作流式 xslt。关于如何实现我的逻辑的任何想法?

标签: xml xslt saxon xslt-3.0


【解决方案1】:

流模式下的模板规则必须具有静止的匹配模式。在这种情况下,“不动”本质上意味着您可以在解析器位于元素开始标记处时评估模式。在这种情况下您不能这样做,因为谓词测试是否存在 Addl_Information 子代和 Plan 孙子代,如果不向前读取开始标签之外的内容,您无法判断它们是否存在。

我很高兴查看整个样式表,看看我是否可以提出任何建议以使其可流式传输,前提是它相当紧凑。

==以后==

您可以使用在遇到每个 Worker 元素时对其进行复制的方法,在这种情况下,您只需在复制的元素内进行所有后续访问:

<xsl:variable name="ThisPerson" select="copy-of()"/> 
<xsl:if test="$ThisPerson/Additional_Information/ws:plan">
    <Row>
        <A1_Account_Number><xsl:value-of select="$ThisPerson/Additional_Information/Account_Number"/>   </A1_Account_Number>
        <A2_Employee_Number>...</A2_Employee_Number>
    </Row>
</xsl:if>

这可能是最简单的解决方案。可能有避免复制操作的方法(取决于确切的源文档结构),但它会更复杂,除非单个 Worker 元素非常大,否则不值得努力。

【讨论】:

  • 这正是我使用的。感谢您的帮助!
【解决方案2】:

我建议使用

    <xsl:template match="Worker_Sync">
        <File>
            <xsl:apply-templates select="copy-of(Worker)[Addl_Information/Plan]" mode="some-non-streamable-mode"/>    
        </File>
    </xsl:template>

然后在Worker 的模板中,您不需要测试,只需

    <xsl:template match="Worker" mode="some-non-streamable-mode">
            <Row>
                <A1_Account_Number><xsl:value-of select="Additional_Information/Account_Number"/></A1_Account_Number>
                <A2_Employee_Number>...</A2_Employee_Number>
            </Row>
    </xsl:template>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-04
    • 2019-05-22
    • 1970-01-01
    • 1970-01-01
    • 2018-04-18
    相关资源
    最近更新 更多