XSLT:不允许将一个以上项目的序列作为concat()的第一个参数

 豆芽哥的马甲_206 发布于 2023-02-12 18:55

我正在尝试生成一个页面列表,其中包含各种div(@chapter)|(@part)的ID的串联。我的问题源于嵌套结构:@part可以包含任意数量的@chapter。我只想按文档顺序选择页码的最后祖先的ID。

以下是XML的代码段:


    

以下是我的XSLT:



    
    
        
            
        
        
            
        
    
    

    
        
        
        
            
                    
                    
                
        
    


但是,我不断收到错误消息:concat()的第一个参数不允许包含多个项目的序列。显然,由于@part和@chapters,我的XPath在第一个参数中选择了多个字符串。如何将选择范围限制为class ='page'的第一个祖先?

这是上述示例的期望输出:


小智.. 5

首先,Xpath中的管道符号不是您正在考虑的“或”。它执行的操作将两个独立的查询合并,并将它们作为一个节点集返回。所以发生了什么事,您对章节的查询都返回一个元素(第一个节点的@id属性),然后将其组合返回一个具有两个节点的节点集。因此,为什么concat会有问题。

您可以这样做:

(ancestor::div[@class='chapter'] | ancestor::div[@class='part'])[1]/@id

但这是错误的!因为这将是合并系列中的第一篇,但不会将它们合并到正确的文档顺序中。因此,在获得参与资格之前,总是会获得一章。

您需要的是:

ancestor::div[@class='chapter' or @class='part'][1]/@id

我不确定为什么要使用concat已经concat编辑过的东西。另外,如果要concat使用字符串并创建属性,则可以将其括在花括号中以使XSLT更短,如下所示:


    
    
    
  • 编辑:如果要继续使用xsl:attribute元素,可以使用concat,如以下模板所示:

    
        
        
        
  • 它有点冗长,这就是为什么我更喜欢内联属性值。

    1 个回答
    • 首先,Xpath中的管道符号不是您正在考虑的“或”。它执行的操作将两个独立的查询合并,并将它们作为一个节点集返回。所以发生了什么事,您对章节的查询都返回一个元素(第一个节点的@id属性),然后将其组合返回一个具有两个节点的节点集。因此,为什么concat会有问题。

      您可以这样做:

      (ancestor::div[@class='chapter'] | ancestor::div[@class='part'])[1]/@id
      

      但这是错误的!因为这将是合并系列中的第一篇,但不会将它们合并到正确的文档顺序中。因此,在获得参与资格之前,总是会获得一章。

      您需要的是:

      ancestor::div[@class='chapter' or @class='part'][1]/@id
      

      我不确定为什么要使用concat已经concat编辑过的东西。另外,如果要concat使用字符串并创建属性,则可以将其括在花括号中以使XSLT更短,如下所示:

      <xsl:template match="a[@class='page']" mode="pagelist">
          <xsl:variable name="html" select="ancestor::div[@class='chapter' or @class='part'][1]/@id"/>
          <xsl:variable name="pagenumber" select="substring-after(@id,'-')"/>
          <li>
              <a href="{$html}.xhtml#page{$pagenumber}">
                  <xsl:value-of select="$pagenumber"/>
              </a>
          </li>
      </xsl:template>
      

      编辑:如果要继续使用xsl:attribute元素,可以使用concat,如以下模板所示:

      <xsl:template match="a[@class='page']" mode="pagelist">
          <xsl:variable name="html" select="ancestor::div[@class='chapter' or @class='part'][1]/@id"/>
          <xsl:variable name="pagenumber" select="substring-after(@id,'-')"/>
          <li>
              <a>
                  <xsl:attribute name="href">
                      <xsl:value-of select="concat($html,'.xhtml#page',$pagenumber)"/>
                  </xsl:attribute>
                  <xsl:value-of select="$pagenumber"/>
              </a>
          </li>
      </xsl:template>
      

      它有点冗长,这就是为什么我更喜欢内联属性值。

      2023-02-12 18:59 回答
    撰写答案
    今天,你开发时遇到什么问题呢?
    立即提问
    热门标签
    PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
    Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有