【问题标题】:Ordering some XML nodes订购一些 XML 节点
【发布时间】:2021-05-22 12:11:48
【问题描述】:

我正在使用 XSLT 1.0

我正在尝试转换一条输入消息。该输入消息由 4 种类型的节点 A、B、Order、Article 组成。喜欢这个:

A
B
Order0
Article100
Article102
A
B
Order1
Article101
A
B
A
B
A
B
etc

我的目标是将A和B节点放在消息的开头,所以我有:

A
B
A
B
A
B
A
B
A
B
Order0
Article100
Article102
Order1
Article101

这是一个例子:

输入

<Messages>
    <Message>
        <A>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </A>
    </Message>
    <Message>
        <B>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </B>
    </Message>
    <Message>
        <Order>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </Order>
    </Message>
    <Message>
        <Article>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </Article>
    </Message>
    <Message>
        <Article>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </Article>
    </Message>
    <Message>
        <A>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </A>
    </Message>
    <Message>
        <B>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </B>
    </Message>
    <Message>
        <Order>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </Order>
    </Message>
    <Message>
        <Article>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </Article>
    </Message>
    <Message>
        <A>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </A>
    </Message>
    <Message>
        <B>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </B>
    </Message>
</Messages>

输出

<Messages>
    <Message>
        <A>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </A>
    </Message>
    <Message>
        <B>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </B>
    </Message>
    <Message>
        <A>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </A>
    </Message>
    <Message>
        <B>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </B>
    </Message>
    <Message>
        <A>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </A>
    </Message>
    <Message>
        <B>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </B>
    </Message>
    <Message>
        <Order>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </Order>
    </Message>
    <Message>
        <Article>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </Article>
    </Message>
    <Message>
        <Article>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </Article>
    </Message>
    <Message>
        <Order>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </Order>
    </Message>
    <Message>
        <Article>
            <SomeData>somedata</SomeData>
            <SomeData2>somedata</SomeData2>
        </Article>
    </Message>
</Messages>

不幸的是,由于我正在开发旧版本的 Biztalk,因此我受到 xslt 1.0 的限制。 我考虑过可能使用 order by,但只针对那些 A 和 B 节点。

【问题讨论】:

    标签: xml xslt mapping xslt-1.0 biztalk


    【解决方案1】:

    如果您真的只有这些元素要排序,您可以直接命名它们,如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0">
    
      <xsl:output method="xml" indent="yes"/>
      
      <!-- Identity transform -->
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="Messages">
          <xsl:copy>
            <xsl:apply-templates select="Message[A or B]"/>
            <xsl:apply-templates select="Message[not(A) and not(B)]"/>
          </xsl:copy>
      </xsl:template>
      
    </xsl:stylesheet>
    

    在这里查看它的工作原理:https://xsltfiddle.liberty-development.net/gVrvcy1/1

    【讨论】:

    • 完美运行
    【解决方案2】:

    如果你想通过排序来做到这一点,你可以这样做:

    XSLT 1.0

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
    
    <xsl:template match="/Messages">
        <xsl:copy>
            <xsl:for-each select="Message">
                <xsl:sort select="number(A or B)" data-type="number" order="descending"/>
                <xsl:copy-of select="."/>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

      猜你喜欢
      • 2019-04-30
      • 2016-03-01
      • 2013-09-21
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-29
      • 2014-10-05
      相关资源
      最近更新 更多