【问题标题】:Missing something re: matching缺少一些东西:匹配
【发布时间】:2015-09-17 10:46:02
【问题描述】:

我是 XSLT 的新手,遇到了一些我认为应该可行但不可行的问题。我很困惑,希望你能提供帮助。

我有以下代码:

<xsl:template match="text()" name="multiReplace">
    <xsl:param name="pText" select="."/>

    <xsl:variable name="patterns">
        <pattern>
            <old>A</old>
            <new>B</new>
        </pattern>
        <pattern>
            <old>v</old>
            <new>w</new>
        </pattern>
    </xsl:variable>

    <xsl:if test="string-length($pText) >0">
        <xsl:variable name="matchingPatterns" select="$patterns[starts-with($pText, old/node())]"/>

    <!-- Do something with the tree fragment "matchingPatterns" -->

    </xsl:if>
</xsl:template>

据我了解,select="$patterns[starts-with($pText, old/node())]" 应该只匹配 patterns 树中节点 old 与字符串 $pText 的开头匹配的元素。相反,$matchingPatterns 包含patterns 树中的所有节点。我知道$pText 不包含任何大写的“A”字符但包含小写的“v”。

我错过了什么明显的错误吗?

感谢您的帮助!

-j

ps,这段代码的要点来自这个问题:XSL Multiple search and replace function。该代码是为 XSLT 1 编写的;我们使用的是 2,但不知何故,它对我来说无法正常工作。

【问题讨论】:

  • 如果您使用的是 XSLT 2.0,那么您为什么要使用递归命名模板而不是使用 replace() 函数呢?
  • 可能相关:如果我用文字“A”代替old/node()$matchingPatterns 为空;如果我用文字 'v' 替换 $matchingPatterns 包含 patterns 中的所有元素。
  • @michael.hor257k 我不能使用replace(),因为我需要替换多个模式。这些模式并不总是单个字符,所以translate() 也没有用。
  • "我不能使用 replace(),因为我需要替换多个模式。" 这不是原因:只需将几个 replace() 函数嵌套在一起。
  • @michael.hor257k - 谢谢,但我想我也想了解一下 XSLT 的工作原理。我绝对可以嵌套replace() 语句,但我想知道为什么我的示例不起作用。

标签: xml xslt replace translate


【解决方案1】:

给定

<xsl:variable name="patterns">
    <pattern>
        <old>A</old>
        <new>B</new>
    </pattern>
    <pattern>
        <old>v</old>
        <new>w</new>
    </pattern>
</xsl:variable>

在 XSLT 2.0 中,变量是一个树片段,由包含两个 pattern 元素的根节点组成,因此您的变量定义应该是

<xsl:variable name="matchingPatterns" select="$patterns/pattern[starts-with($pText, old)]"/>

选择那些满足条件的pattern元素。

作为替代方案,使用&lt;xsl:variable name="matchingPatterns" select="$patterns[starts-with($pText, old)]"/&gt;,但请确保您已设置

<xsl:variable name="patterns" as="element(pattern)*">
    <pattern>
        <old>A</old>
        <new>B</new>
    </pattern>
    <pattern>
        <old>v</old>
        <new>w</new>
    </pattern>
</xsl:variable>

在这种情况下,您的patterns 变量是一系列无父pattern 元素,而不是根节点包含pattern 元素的树片段。

【讨论】:

  • 试试这个,我的编辑(氧气)告诉我,Required item type of value of variable $patterns is element(Q{}pattern); supplied value has item type element(pattern, xs:untyped)。就像许多来自 XSLT 处理器的错误一样,这对我来说毫无意义;具体来说,我不确定“Q{}模式”指的是什么。有什么见解吗?
  • 我不确定这个问题来自哪里。 Oxygen 是否显示任何错误代码?您在 Oxygen 中使用哪个版本的 Saxon?您能否向我们展示任何上下文,例如可能在范围内的默认命名空间声明?
  • 是的,对于大多数这些事情。它是 Saxon-HE 9.6.0.5,错误代码是 F-XTTE0570。编译失败,因此没有上下文,但 xmlns="http://www.cdisc.org/ns/odm/v1.3" 标记上有 xmlns="http://www.cdisc.org/ns/odm/v1.3"(我认为这是默认设置。)
  • 尝试使用&lt;xsl:variable name="patterns" as="element(pattern)*" xmlns=""&gt;...&lt;/xsl:variable&gt; 设置变量,使其内部创建的pattern 元素不在命名空间中。
【解决方案2】:

虽然您可以使用 old/node(),但这可能并不总是有效,因为它会匹配任何节点而不仅仅是文本节点。

我认为问题在于您没有迭代模式中的值。 您应该添加一个 for-each。

<xsl:for-each select="old">
    ...
</xsl:for-each>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多