如何在 XSL 中按顺序将所有消息连接在一起?

Posted

技术标签:

【中文标题】如何在 XSL 中按顺序将所有消息连接在一起?【英文标题】:How to concatenate all messages together in order of sequence in XSL? 【发布时间】:2018-06-14 00:19:52 【问题描述】:

假设我得到以下 XML:

<Gift>
            <GiftWrapId>026272275</GiftWrapId>
            <ClientIItemId>191267166704</ClientIItemId>
            <GiftMessageSequence>1</GiftMessageSequence>
            <GiftMessageType>GIFT</GiftMessageType>
            <GiftMessage>Happy Birthday, sweet</GiftMessage>
        </Gift>
        <Gift>
            <GiftWrapId>026272275</GiftWrapId>
            <ClientIItemId>191267166704</ClientIItemId>
            <GiftMessageSequence>2</GiftMessageSequence>
            <GiftMessageType>GIFT</GiftMessageType>
            <GiftMessage>Konnie</GiftMessage>
        </Gift>

我希望结果是“生日快乐,亲爱的康妮”,但按照“GiftMessageSequence”标签中提到的顺序连接“GiftMessage”:

<CommentInfo>
 <CommentType>X</CommentType>
  <xsl:element name="CommentText">
   <xsl:value-of select="*Happy Birthday, sweet Konnie should come here*"/>
  </xsl:element>
</CommentInfo>

【问题讨论】:

像许多 XSLT 问题一样,最佳解决方案在 XSLT 1.0 和 2.0 之间有所不同,而且由于这两个版本都很常用,所以您应该始终说明您使用的是哪个版本。 【参考方案1】:

假设&lt;GiftMessageSequence&gt;有一个数值,你可以对节点进行排序,然后将&lt;GiftMessage&gt;中的值连接起来得到完整的消息。

将输入 XML 包装在 &lt;root&gt; 节点中并在其上应用以下 XSLT,将提供所需的输出。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"  />
    <xsl:strip-space elements="*" />

    <xsl:template match="root">
        <xsl:variable name="message">
            <xsl:for-each select="Gift">
                <xsl:sort select="GiftMessageSequence" data-type="number" order="ascending" />
                <xsl:value-of select="concat(GiftMessage, ' ')" />
            </xsl:for-each>
        </xsl:variable>
        <CommentInfo>
            <CommentType>X</CommentType>
            <CommontText>
                <xsl:value-of select="normalize-space($message)" />
            </CommontText>
        </CommentInfo>
    </xsl:template>
</xsl:stylesheet>

输出

<CommentInfo>
    <CommentType>X</CommentType>
    <CommontText>Happy Birthday, sweet Konnie</CommontText>
</CommentInfo>

【讨论】:

谢谢。不得不稍作修改以使其适用于我现有的代码,但它确实有效。【参考方案2】:

由于您的来源包含多个 Gift 标签,因此它们必须是 包含在一些 root 标记中(为了形成正确的 XML)。

那么,在XSLT 2.0中,脚本可以如下:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <CommentInfo>
      <CommentType>X</CommentType>
      <CommentText>
        <xsl:variable name="msg">
          <xsl:for-each select="*/Gift">
            <xsl:sort select="GiftMessageSequence"/>
            <xsl:copy-of select="."/>
          </xsl:for-each>
        </xsl:variable>
        <xsl:value-of select="$msg/Gift//GiftMessage"/>
      </CommentText>
    </CommentInfo>
  </xsl:template>
</xsl:stylesheet>

msg 变量收集所有Gift 元素,并按 GiftMessageSequence。 请注意,XPath 表达式从 * 开始以匹配 any 根标记名称。

XSLT 2.0 中的

value-of 指令打印所有 选定标记的值,默认分隔符等于空格。

【讨论】:

以上是关于如何在 XSL 中按顺序将所有消息连接在一起?的主要内容,如果未能解决你的问题,请参考以下文章

如何在一行中按顺序对所有项目的总金额进行分组

如何在 Core Data 中按顺序存储数据? [复制]

我如何测试使用硒在下拉菜单中按字母顺序对项目进行排序

如何在 AppDelegate.swift 中按常规顺序调用 ViewController

如何在所有行中按顺序更新组号

如何从内部连接的第二个表中按列选择前 1 个顺序 desc?