首页 > 解决方案 > XSLT for-each,试图创建标题行结构

问题描述

这不是浏览器类型 XSLT,这是用于处理数据(SAP B1 集成框架)。假设我们有两个 SQL 表,HEADER 和 LINE,我们希望避免首先从 HEADER 中选择然后为每个行启动单独选择的工作,因为这需要“可视化编程”,我们喜欢编写代码不仅仅是连接箭头。所以我们向服务器发送一个查询,如 SELECT * FROM HEADER, SELECT * FROM LINES,我们得到一个大致如下的 XML:

<ResultSets>
<ResultSet>
    <Row><MHeaderNum>1</MHeaderNum></Row>
    <Row><MHeaderNum>2</MHeaderNum></Row>
    <Row><MHeaderNum>3</MHeaderNum></Row>
</ResultSet>

<ResultSet>
    <Row><LineNum>1</LineNum> <HeaderNum>1</HeaderNum></Row>
    <Row><LineNum>2</LineNum> <HeaderNum>2</HeaderNum></Row>
    <Row><LineNum>1</LineNum> <HeaderNum>3</HeaderNum></Row>
    <Row><LineNum>2</LineNum> <HeaderNum>1</HeaderNum></Row>
    <Row><LineNum>1</LineNum> <HeaderNum>2</HeaderNum></Row>
    <Row><LineNum>2</LineNum> <HeaderNum>3</HeaderNum></Row>
</ResultSet>

所以我们认为我们是命令式的、程序化的程序员,并且拉

<xsl:for-each select="//ResultSets/Resultset[1]/Row">
   do stuff with header data
   <xsl:for-each select="//ResultSets/Resultset[2]/Row[HeaderNum=MHeaderNum]">
      do stiff with the line data beloning to this particular header
   </xsl:for-each>  
</xsl:for-each>

当然,这不起作用,因为 MHeaderNum 像 grunge 过时一样脱离了上下文,我们也不能将它保存到变量中,因为我们不会更新该变量,因为 XSLT 是一种不可变的函数式编程语。

但不要害怕,一个内心的声音说,因为 XSLT 专家可以使用模板解决类似的问题。模板,如果我理解的话,是某种 XSLT 的功能。它们可以是递归的和类似的东西。那么它们可以用来解决这样的问题吗?

当然,我们谈论的是 XSLT 1.0,因为我不知道 Java 是否曾经费心实现更高版本,但 SAP 肯定不会费心使用所谓的假设实现。

还是我真的应该忘记这一点,只连接我的视觉箭头?问题是,SQL 不应该用于这样的迭代标头然后迭代行的方式。我想做的是让 SQL 数据库变得快乐,从中获取大量数据,然后在其他地方处理它,而不是用 70 亿个小查询来打扰它。在我们的例子中,其他地方很遗憾是 XSLT,虽然从技术上讲我可以尝试 JavaScript 以及 SAP 也为这堆混乱添加了 Nashorn,但也许它可以在“纯”XSL 中解决?

标签: sqlxmlxsltxslt-1.0sapb1

解决方案


无论是 XSLT 1 还是更高版本,以及是否带有模板和 for-each,current()函数都存在://ResultSets/Resultset[2]/Row[HeaderNum=current()/MHeaderNum].


推荐阅读