【问题标题】:XSLT Sort nested xmlXSLT 对嵌套的 xml 进行排序
【发布时间】:2017-02-27 18:42:54
【问题描述】:

我需要根据 E1EDP01 - POSEX 和 ACTION 从 SAP 中对以下 XML 进行排序,其余的 xml 应按原样复制。请注意,E1EDP01 下有 E1EDP19,也应照原样复制。我的 XSLT 不工作,因为我不确定模板匹配的值应该是什么。请帮忙。

<ORDERS05>
 <IDOC BEGIN="1">

 <E1EDK14 SEGMENT="1">
        <QUALF>014</QUALF>
        <ORGID>PF01</ORGID>
    </E1EDK14>


 <E1EDP01 SEGMENT="1">
        <POSEX>00020</POSEX>
        <ACTION>001</ACTION>
        <PSTYP>0</PSTYP>
        <MENGE>540.000</MENGE>
        <MENEE>RO</MENEE>
       <E1EDP19>
          <Text> Test 2 </Text>
        </E1EDP19>
 </E1EDP01>
 <E1EDP01 SEGMENT="1">
        <POSEX>00030</POSEX>
        <ACTION>001</ACTION>
        <PSTYP>1</PSTYP>
        <MENGE>140.000</MENGE>
        <MENEE>AD</MENEE>
        <E1EDP19>
          <Text> Test 1 </Text>
        </E1EDP19>
 </E1EDP01>

 <E1EDS01 SEGMENT="1">
        <SUMID>002</SUMID>
        <SUMME>832.2</SUMME>
        <SUNIT>USD</SUNIT>
    </E1EDS01>

</IDOC>
</ORDERS05>


 <xsl:stylesheet version="1.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <!--                                                --> 
  <xsl:strip-space elements="*"/>
  <!--                                                --> 
    <xsl:template match="node()|@*">
     <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
   </xsl:template>
   <!--                                                --> 
 <xsl:template match="E1EDP01">
<xsl:copy>
  <xsl:apply-templates select="@*"/>
  <xsl:apply-templates select="POSEX">
    <xsl:sort select="POSEX" order="descending" data-type="number"/>
     </xsl:apply-templates>
   </xsl:copy>
  </xsl:template>
</xsl:stylesheet>


  Expected Result

  <ORDERS05>
  <IDOC BEGIN="1">

  <E1EDK14 SEGMENT="1">
    <QUALF>014</QUALF>
    <ORGID>PF01</ORGID>
    </E1EDK14>

    <E1EDP01 SEGMENT="1">
      <POSEX>00030</POSEX>
      <ACTION>001</ACTION>
     <PSTYP>1</PSTYP>
    <MENGE>140.000</MENGE>
    <MENEE>AD</MENEE>
    <E1EDP19>
      <Text> Test 1 </Text>
    </E1EDP19>
 </E1EDP01>


  <E1EDP01 SEGMENT="1">
    <POSEX>00020</POSEX>
    <ACTION>001</ACTION>
    <PSTYP>0</PSTYP>
    <MENGE>540.000</MENGE>
    <MENEE>RO</MENEE>
   <E1EDP19>
      <Text> Test 2 </Text>
    </E1EDP19>
  </E1EDP01>


  <E1EDS01 SEGMENT="1">
    <SUMID>002</SUMID>
    <SUMME>832.2</SUMME>
    <SUNIT>USD</SUNIT>
  </E1EDS01>

 </IDOC>
 </ORDERS05>

【问题讨论】:

  • 那么对于您发布的输入样本,您想要哪个结果?有两个E1EDP01,不是已经按POSEXACTION排序了吗?
  • 降序排列。 00030 应该在 00020 之前
  • 请至少向我们展示您想要的结果,以及 - 充其量 - 您尝试解决此问题的方法。

标签: xslt xslt-1.0 xslt-2.0


【解决方案1】:

如果您想对E1EDP01 元素进行排序,则可以在处理父元素子元素的模板的xsl:apply-templates 中使用xsl:sort

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*[E1EDP01]">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:for-each-group select="node()" group-adjacent="boolean(self::E1EDP01)">
                <xsl:choose>
                    <xsl:when test="current-grouping-key()">
                         <xsl:apply-templates select="current-group()">
                            <xsl:sort select="POSEX" order="descending"/>
                            <xsl:sort select="ACTION" order="descending"/>
                        </xsl:apply-templates>                        
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="current-group()"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each-group>        
        </xsl:copy>
    </xsl:template>

</xsl:transform>

http://xsltransform.net/ncntCT9/1 有一个在线示例。

【讨论】:

  • 当我运行它时,我收到错误 javax.xml.transform.TransformerException: java.lang.RuntimeException: Unsupported XSL element 'w3.org/1999/XSL/Transform:for-each-group'
  • 这个问题被标记为 XSLT 2.0,所以我发布了一个 XSLT 2.0 解决方案,它当然需要一个 XSLT 2.0 处理器,例如 Saxon 9,它可用于 Maven 和 Sourceforge 上的 Java。
  • 谢谢。但是有没有办法使用 XSLT 1.0 实现相同的结果?
猜你喜欢
  • 1970-01-01
  • 2021-10-17
  • 2020-09-11
  • 1970-01-01
  • 2019-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多