在 XSL 中使用定界符将字符串粘合在一起

Gluing together strings with delimiters in XSL

我有以下结构,我想从中找出最相关的数据并将其粘合在一起以制作标题。

<faults>
  <fault componentName="comp1">
    <introduceWhen>Time1</introduceWhen>
    <signals>
      <signal name="sig11" value="1"/>
      <signal name="sig22" value="1"/>
    </signals>
  </fault>
  <fault componentName="comp2">
    <introduceWhen>Time2</introduceWhen>
    <signals>
      <signal name="sig44" value="0"/>
    </signals>
  </fault>
</faults>

我希望它是 comp1 1 1 comp2 0,但到目前为止,我做到的最好的是 comp1 1 1comp2 0,使用这个:

<xsl:template match="faults">
  <xsl:for-each select="fault">
    <xsl:variable name="compName" select="@componentName"/>
    <xsl:variable name="sigVals" select="string-join(signals/signal/@value, ' ')"/>
    <xsl:value-of select="concat(@compName, ' ', $sigVals)"/>
  </xsl:for-each>
</xsl:template>

我的解决方案感觉不是很优雅,所以如果你有替代方法,我非常希望看到它们。我也完全控制了 XML,所以如果有任何好的解决方案可以改变 XML 的结构,那也会很有趣。

由于您似乎使用的是 XSLT 2.0,因此您可以简单地使用它:

<xsl:template match="/faults">
    <xsl:for-each select="fault">
        <xsl:value-of select="@componentName, signals/signal/@value"/>
        <xsl:text> </xsl:text>
    </xsl:for-each>
</xsl:template>

或者,如果你想更细致一点:

<xsl:template match="/faults">
    <xsl:for-each select="fault">
        <xsl:value-of select="@componentName, signals/signal/@value"/>
        <xsl:if test="position()!=last()">
            <xsl:text> </xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

或者(从 Michael Kay 的回答中得到提示)更简单:

<xsl:template match="/faults">
    <xsl:value-of select="fault/@componentName | fault/signals/signal/@value"/>
</xsl:template>

xsl:value-of 指令已经在各个值之间插入了分隔符;不需要使用 string-join().

不就是

string-join((//@componentName | //@value), ' ')

?