XSL通过排序、添加和删除元素使转换复杂化



我试图使用XSLT转换XML文档,但遇到了困难,因为要对XML文档执行多个处理任务。

以下是我想要完成的步骤(对不起,我不确定这是否可能,或者我是否必须尝试其他方法):

1-剥离/移除所有<group>元素,并将相邻的<relation>元素放入/移动到下一个<filter>元素中

2-根据称为<relation><filtertype> 的两个元素对所有<filter>元素进行排序

3-通过将<group>元素相加并从<group> 中的第一个<filter>元素中取出<relation>元素,将所有<filter>元素按<relation><filtertype>重新分组

换言之,我正试图撤消所有现有的分组,根据类似的filtertype和relation对所有过滤元素进行排序,然后根据公共的filtertyype和relation重新分组过滤器,因为我知道第一个组元素必须有一个从其第一个过滤元素移到组元素中的relation元素

很抱歉,如果这让人困惑,我的样品在下面(提前感谢)

输入XML

<mainXML>
   <version major="1" minor="0" build="0" revision="0"/>
   <id>30</id>
   <set>Partial</set>
   <evaluate>True</evaluate>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>GreaterThanOrEqualTo</operator>
            <value>01001</value>
         </action>
      </filter>
      <filter>
         <relation>Or</relation>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>LessThanOrEqualTo</operator>
            <value>26886</value>
         </action>
      </filter>
   </group>
   <group>
      <relation>Or</relation>
      <filter>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>GreaterThanOrEqualTo</operator>
            <value>30001</value>
         </action>
      </filter>
   </group>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Grouping</filtertype>
         <action>
            <type>Mailing</type>
            <operator>DoNotBelongTo</operator>
            <groupingid>1133519</groupingid>
         </action>
      </filter>
      <filter>
         <relation>And</relation>
         <filtertype>Action</filtertype>
         <campaign>
            <campaignid>1509779</campaignid>
         </campaign>
         <action>
            <status>DoNot</status>
            <operator>Bill</operator>
         </action>
         <operator>AfterNHour</operator>
         <value>36</value>
      </filter>
      <filter>
         <relation>Or</relation>
         <filtertype>Action</filtertype>
         <campaign>
            <campaignid>1509779</campaignid>
         </campaign>
         <action>
            <status>DoNot</status>       
         </action>
         <operator>AfterNHour</operator>
         <value>36</value>
      </filter>
   </group>
</mainXML>

所需输出XML

<mainXML>
   <version major="1" minor="0" build="0" revision="0"/>
   <id>30</id>
   <set>Partial</set>
   <evaluate>True</evaluate>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Action</filtertype>
         <campaign>
            <campaignid>1509779</campaignid>
         </campaign>
         <action>
            <status>DoNot</status>
            <operator>Bill</operator>
         </action>
         <operator>AfterNHour</operator>
         <value>36</value>
      </filter>
   </group>
   <group>
      <relation>Or</relation>
      <filter>
         <filtertype>Action</filtertype>
         <campaign>
            <campaignid>1509779</campaignid>
         </campaign>
         <action>
            <status>DoNot</status>
         </action>
         <operator>AfterNHour</operator>
         <value>36</value>
      </filter>
   </group>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Grouping</filtertype>
         <action>
            <type>Mailing</type>
            <operator>DoNotBelongTo</operator>
            <groupingid>1133519</groupingid>
         </action>
      </filter>
   </group>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>GreaterThanOrEqualTo</operator>
            <value>01001</value>
         </action>
      </filter>
   </group>
   <group>
      <relation>Or</relation>
      <filter>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>LessThanOrEqualTo</operator>
            <value>26886</value>
         </action>
      </filter>
      <filter>
         <relation>Or</relation>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>GreaterThanOrEqualTo</operator>
            <value>30001</value>
         </action>
      </filter>
   </group>
</mainXML>

此转换:

<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:key name="kFilterRel" match="filter"
  use="concat(filtertype,'+'
              , (preceding-sibling::*[1]
                            [self::relation]
               | relation
                )[1]
              )"/>
 <xsl:template match="node()|@*" name="identity">
  <xsl:param name="pPos"/>
  <xsl:copy>
   <xsl:apply-templates select="node()|@*">
     <xsl:with-param name="pPos" select="$pPos"/>
   </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>
 <xsl:template match="/*">
  <xsl:copy>
   <xsl:apply-templates select="@*|*[not(self::group)]"/>
   <xsl:apply-templates select=
     "*/filter
        [generate-id()
        =
         generate-id(key('kFilterRel',
                         concat(filtertype,'+'
                                , (preceding-sibling::*[1]
                                             [self::relation]
                                  | relation
                                  )[1]
                               )
                         )
                         [1]
                     )]">
    <xsl:sort select="filtertype"/>
    <xsl:sort select="(preceding-sibling::*[1]
                                   [self::relation]
                     | relation)[last()]"/>
   </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>
 <xsl:template match="filter">
  <group>
    <xsl:variable name="vRelation"
        select="(preceding-sibling::*[1][self::relation]
               | relation)[last()]"/>
    <xsl:copy-of select="$vRelation"/>
    <xsl:apply-templates mode="inGroup" select=
     "key('kFilterRel',
          concat(filtertype,'+'
                 , (preceding-sibling::relation[1]
                   | relation
                   )[last()]
                )
         )">
       <xsl:with-param name="pRel" select="$vRelation"/>
     </xsl:apply-templates>
  </group>
 </xsl:template>
 <xsl:template match="filter" mode="inGroup">
  <xsl:param name="pRel"/>
  <filter>
      <xsl:if test="not(relation) and position() > 1">
       <xsl:copy-of select="$pRel"/>
      </xsl:if>
      <xsl:apply-templates>
       <xsl:with-param name="pPos" select="position()"/>
      </xsl:apply-templates>
  </filter>
 </xsl:template>
 <xsl:template match="relation">
  <xsl:param name="pPos"/>
  <xsl:if test="$pPos > 1">
   <xsl:copy-of select="."/>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

应用于所提供的XML文档时:

<mainXML>
   <version major="1" minor="0" build="0" revision="0"/>
   <id>30</id>
   <set>Partial</set>
   <evaluate>True</evaluate>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>GreaterThanOrEqualTo</operator>
            <value>01001</value>
         </action>
      </filter>
      <filter>
         <relation>Or</relation>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>LessThanOrEqualTo</operator>
            <value>26886</value>
         </action>
      </filter>
   </group>
   <group>
      <relation>Or</relation>
      <filter>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>GreaterThanOrEqualTo</operator>
            <value>30001</value>
         </action>
      </filter>
   </group>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Grouping</filtertype>
         <action>
            <type>Mailing</type>
            <operator>DoNotBelongTo</operator>
            <groupingid>1133519</groupingid>
         </action>
      </filter>
      <filter>
         <relation>And</relation>
         <filtertype>Action</filtertype>
         <campaign>
            <campaignid>1509779</campaignid>
         </campaign>
         <action>
            <status>DoNot</status>
            <operator>Bill</operator>
         </action>
         <operator>AfterNHour</operator>
         <value>36</value>
      </filter>
      <filter>
         <relation>Or</relation>
         <filtertype>Action</filtertype>
         <campaign>
            <campaignid>1509779</campaignid>
         </campaign>
         <action>
            <status>DoNot</status>
         </action>
         <operator>AfterNHour</operator>
         <value>36</value>
      </filter>
   </group>
</mainXML>

生成所需的正确结果:

<mainXML>
   <version major="1" minor="0" build="0" revision="0"/>
   <id>30</id>
   <set>Partial</set>
   <evaluate>True</evaluate>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Action</filtertype>
         <campaign>
            <campaignid>1509779</campaignid>
         </campaign>
         <action>
            <status>DoNot</status>
            <operator>Bill</operator>
         </action>
         <operator>AfterNHour</operator>
         <value>36</value>
      </filter>
   </group>
   <group>
      <relation>Or</relation>
      <filter>
         <filtertype>Action</filtertype>
         <campaign>
            <campaignid>1509779</campaignid>
         </campaign>
         <action>
            <status>DoNot</status>
         </action>
         <operator>AfterNHour</operator>
         <value>36</value>
      </filter>
   </group>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Grouping</filtertype>
         <action>
            <type>Mailing</type>
            <operator>DoNotBelongTo</operator>
            <groupingid>1133519</groupingid>
         </action>
      </filter>
   </group>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>GreaterThanOrEqualTo</operator>
            <value>01001</value>
         </action>
      </filter>
   </group>
   <group>
      <relation>Or</relation>
      <filter>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>LessThanOrEqualTo</operator>
            <value>26886</value>
         </action>
      </filter>
      <filter>
         <relation>Or</relation>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>GreaterThanOrEqualTo</operator>
            <value>30001</value>
         </action>
      </filter>
   </group>
</mainXML>

相关内容

  • 没有找到相关文章

最新更新