且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在 XSLT 中使用循环搜索节点值?

更新时间:2023-01-16 16:34:34

正如 Ian Roberts 在 他对您之前的问题的回答中已经提出的,如果您学会声明式思考而不是程序式思考,您会在 XSLT 中做得更好.(学习这样做也可能使您成为更好的过程语言程序员,而不仅仅是在 XSLT 方面,但这是您必须承担的风险.)

As Ian Roberts has already suggested in his answer to your earlier question, you will do better in XSLT if you learn to think declaratively rather than procedurally. (Learning to do so may also make you a better programmer in procedural languages, too, and not just in XSLT, but that's a risk you have to take.)

所以首先要做的是停止认为你的目标是在循环中实现像break语句这样的代码".这是一个愚蠢的目标——如果你真的想在循环中使用 break 语句进行编程,那么选择一种具有循环和 break 语句的语言并疯狂.如果您想在 XSLT 中解决您的问题,您需要以声明方式理解您的目标.在过程语言中,您将在这里使用循环——做什么?带有中断的循环语句在过程语言中解决了什么问题?用 XSLT 解决这个问题,就大功告成了.

So the first thing to do is to stop thinking that your goal is "to achieve the code like break statement in loop". That's a silly goal -- if you really want to program with break statements in loops, choose a language that has loops and break statements and go wild. If you want to solve your problem in XSLT, you need to understand your goals declaratively. In a procedural language, you would use a loop here -- to do what? What problem does a loop statement with a break solve in a procedural language? Solve that problem in XSLT, and you're done.

您对目标的描述(不完整且不可信)表明,如果某个 OperatorStation 元素具有名为 Network B 的子节点,则您希望返回 true,否则返回 false.您建议遍历 OperatorStation 元素,寻找一个名为 Network B 的子元素,如果命中一个则返回 true,如果到达终点但未命中一个则返回 false.

Your description of your goal (incomplete and implausible as it is) says you want to return true if some OperatorStation element has a child node named Network B, and false otherwise. You propose to iterate over the OperatorStation elements looking for one with a child named Network B, and return true if you hit one, false if you reach the end without hitting one.

如果存在这样的 OperatorStation 元素,为什么不直接返回 true,否则返回 false?

Why not just return true if such an OperatorStation element exists, false otherwise?

<xsl:template match="/">
  <xsl:choose>
    <xsl:when test="//w3:OperatorStation
                    /w3:Nodes
                    /w3:ChildNodes
                    /w3:Name 
                    = 'Network B'">
      true
    </xsl:when>
    <xsl:otherwise>
      false
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

如果您真正想做的是当且仅当有一个带有名为网络 B"的子节点的 OperatorStation 以及其他其他内容时执行一件事,则将上面的真"和假"替换为适当的说明.

If what you really want to do is do one thing if and only if there is an OperatorStation with a child named 'Network B' and something else otherwise, then replace 'true' and 'false' above with the appropriate instructions.

如果您真正想要做的是设置一个变量来表示是否有一个带有名为网络 B"的子节点的 OperatorStation,那么您可以在不同点的某些条件处理中使用它,然后使用适当的变量设置一个变量XPath 表达式很简单:

If what you really want to do is set a variable to signal whether there is an OperatorStation with a child named 'Network B', so you can use it in some conditional processing at various points, then setting a variable with an appropriate XPath expression is simple:

<xsl:variable name="Opstation-with-child-B"
              select="//w3:OperatorStation
                     [w3:Nodes/w3:ChildNodes
                     /w3:Name = 'Network B']"/> 

这里不需要循环:XPath 负责隐式迭代.

No loop is needed here: XPath takes care of the implicit iteration.

用你的工具思考,而不是反对它们.它让编程变得更有趣.

Think with your tools, not against them. It makes programming a lot more fun.