0

我有这个 xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<o-com-inter xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1">
<rules deplVer="125">
<cre-det-r name="Auto_R_1">
    <act>false</act>
    <thres-curr>000</thres-curr>
    <thress>
        <thres name="Auto_R_125_1">
            <sco>11111</sco>
            <serv-res>
                <serv-res>ABC</serv-res>
            </serv-res>
            <cat>
                <cate>CatA</cate>
            </cat>
            <o-ru-con>
                <co-ru-con b-name="InterMge" name="ac_T_EQ_000">
                    <si-ru-con>
                        <ru-con-ite>
                            <ru-con-ite-lit>
                                <nae1>ac</nae1>
                                <ope>T_EQ</ope>
                                <val1>000</val1>
                            </ru-con-ite-lit>
                            <bId>2</bId>
                        </ru-con-ite>
                    </si-ru-con>
                </co-ru-con>
                <co-ru-con b-name="InterMge" name="ac_T_EQ_001">
                    <si-ru-con>
                        <ru-con-ite>
                            <ru-con-ite-lit>
                                <nae1>ac</nae1>
                                <ope>T_EQ</ope>
                                <val1>001</val1>
                            </ru-con-ite-lit>
                            <bId>2</bId>
                        </ru-con-ite>
                    </si-ru-con>
                </co-ru-con>
                <co-ru-con b-name="InterMge" name="tra_T_EQ_014">
                    <si-ru-con>
                        <ru-con-ite>
                            <ru-con-ite-lit>
                                <nae1>tra</nae1>
                                <ope>T_EQ</ope>
                                <val1>014</val1>
                            </ru-con-ite-lit>
                            <bId>3</bId>
                        </ru-con-ite>
                    </si-ru-con>
                </co-ru-con>
                <co-ru-con b-name="InterMge" name="tra_T_EQ_015">
                    <si-ru-con>
                        <ru-con-ite>
                            <ru-con-ite-lit>
                                <nae1>tra</nae1>
                                <ope>T_EQ</ope>
                                <val1>015</val1>
                            </ru-con-ite-lit>
                            <bId>3</bId>
                        </ru-con-ite>
                    </si-ru-con>
                </co-ru-con>
            </o-ru-con>
            <al>true</al>
        </thres>
    </thress>
    <description> rSId=125 Fp=0.1234567 Dr=1.0 
        rSId=48 SFp=1.0 SDr=1.0_2012-10-10T09:55:09+02:00
    </description>
  </cre-det-r>
  <cre-det-r>
    ....If this block exists, it will contain the same elements as above in the same order, otherwise, this block doesn't exists and the code contains only the preceding "cre-det-r" block.
  </cre-det-r>
 </rules>
</o-com-inter>

我想检查每个bId元素的值。如果此值与o-ru-con元素中的前面或后面的bId元素相同,那么我会将所有不同的co-ru-con块(在整个块o-ru-con中)分组为相同的值bId在一个co-ru-con中,预期的输出文件所示。我尝试使用这个 xsl 文件:

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

<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<!--  -->
<xsl:template match="*">
<xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates/>
</xsl:copy>
</xsl:template> 

<xsl:key name="k1"
match="ru-con-ite-lit[bId = preceding-sibling::ru-con-ite-lit[1]/bId]"
use="generate-id(preceding-sibling::ru-con-ite-lit[not(bId = preceding-sibling::ru-con-ite-lit[1]/bId)][1])"/>

<xsl:template match="ru-con-ite">
<xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates select="ru-con-ite-lit[not(preceding-sibling::ru-con-ite-lit[1]) or not(bId = preceding-sibling::ru-con-ite-lit[1]/bId)]"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="ru-con-ite-lit">
<xsl:copy>
    <xsl:copy-of select="@*"/>
 <!--     <xsl:apply-templates/>-->

    <xsl:apply-templates select=". | key('k1', generate-id())" mode="sp"/>

 </xsl:copy>
</xsl:template>

<xsl:template match="ru-con-ite-lit" mode="sp">

    <xsl:copy-of select="node()[not(self::bId)]"/>

 </xsl:template>

</xsl:stylesheet>

我可以使用这个 xsl 文件删除我的 xml 文件中的元素bId,但是我不能在一个co-ru-con块中将具有相同bId值的不同co- ru-con块分组。预期的输出将如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<o-com-inter xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1">
<rules deplVer="125">
<cre-det-r name="Auto_R_1">
    <act>false</act>
    <thres-curr>000</thres-curr>
    <thress>
        <thres name="Auto_R_125_1">
            <sco>11111</sco>
            <serv-res>
                <serv-res>ABC</serv-res>
            </serv-res>
            <cat>
                <cate>CatA</cate>
            </cat>
            <o-ru-con>
                <co-ru-con b-name="InterMge" name="bId2"><!-- the value of name here has been changed by the tag-name "bId" and the value 2 of this one -->
                    <si-ru-con>
                        <ru-con-ite>
                            <ru-con-ite-lit>
                                <nae1>ac</nae1>
                                <ope>T_EQ</ope>
                                <val1>000</val1>
                            </ru-con-ite-lit>
                            <!-- Here was the element <bId> with the value 2 and this has been deleted after the transformation -->
                        </ru-con-ite>
                    </si-ru-con>
                    <si-ru-con>
                        <ru-con-ite>
                            <ru-con-ite-lit>
                                <nae1>ac</nae1>
                                <ope>T_EQ</ope>
                                <val1>001</val1>
                            </ru-con-ite-lit>
                            <!-- Here was the element <bId> with the value 2 and this has been deleted after the transformation -->
                        </ru-con-ite>
                    </si-ru-con>
                </co-ru-con>
                <co-ru-con b-name="InterMge" name="bId3"><!-- the value of name here has been changed by the tag-name "bId" and the value 3 of this one -->
                    <si-ru-con>
                        <ru-con-ite>
                            <ru-con-ite-lit>
                                <nae1>tra</nae1>
                                <ope>T_EQ</ope>
                                <val1>014</val1>
                            </ru-con-ite-lit>
                            <!-- Here was the element <bId> with the value 3and this has been deleted after the transformation -->
                        </ru-con-ite>
                    </si-ru-con>
                    <si-ru-con>
                        <ru-con-ite>
                            <ru-con-ite-lit>
                                <nae1>tra</nae1>
                                <ope>T_EQ</ope>
                                <val1>015</val1>
                            </ru-con-ite-lit>
                            <!-- Here was the element <bId> with thw value 3 and this has been deleted after the transformation -->
                        </ru-con-ite>
                    </si-ru-con>
                </co-ru-con>
            </o-ru-con>
            <al>true</al>
        </thres>
    </thress>
    <description> rSId=125 Fp=0.1234567 Dr=1.0 
        rSId=48 SFp=1.0 SDr=1.0_2012-10-10T09:55:09+02:00
    </description>
</cre-det-r>
<cre-det-r>
    ....If this block exists, it will contain the same elements as above in the same order, otherwise, this block doesn't exists and the code contains only the preceding "cre-det-r" block.
</cre-det-r>

谢谢

4

1 回答 1

2

这看起来像是一个分组问题,在 XSLT1.0 中,这是 Muenchian Grouping 的工作。在您的情况下,您通过父o-ru-con元素及其后代bId元素的组合对co-run-con元素进行分组。因此,您将首先为此定义一个密钥

<xsl:key 
   name="con" 
   match="co-ru-con" 
   use="concat(generate-id(..), '|', si-ru-con/ru-con-ite/bId)" />

然后,每当您匹配一个o-ru-con元素时,您将通过查找在键中第一次出现该元素的此类元素来匹配不同的co-ru-con

<xsl:apply-templates 
   select="co-ru-con
      [generate-id() 
         = generate-id(key('con', concat(generate-id(..), '|', si-ru-con/ru-con-ite/bId))[1])]" />

这将允许您为组创建单个co-ru-con元素。然后,您将像这样匹配组的子si-ru-con元素

<xsl:apply-templates 
 select="key('con', concat(generate-id(..), '|', si-ru-con/ru-con-ite/bId))/si-ru-con" />

这是完整的 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:key name="con" match="co-ru-con" use="concat(generate-id(..), '|', si-ru-con/ru-con-ite/bId)" />

   <xsl:template match="o-ru-con">
      <o-ru-con>
         <xsl:apply-templates select="co-ru-con[generate-id() = generate-id(key('con', concat(generate-id(..), '|', si-ru-con/ru-con-ite/bId))[1])]" />
      </o-ru-con>
   </xsl:template>

   <xsl:template match="co-ru-con">
      <co-ru-con b-name="{@b-name}" bId="{si-ru-con/ru-con-ite/bId}">
         <xsl:apply-templates select="key('con', concat(generate-id(..), '|', si-ru-con/ru-con-ite/bId))/si-ru-con" />
      </co-ru-con>
   </xsl:template>

   <xsl:template match="bId" />

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

应用于您的示例 XML 时,将输出以下内容

<o-com-inter version="1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <rules deplVer="125">
      <cre-det-r name="Auto_R_1">
         <act>false</act>
         <thres-curr>000</thres-curr>
         <thress>
            <thres name="Auto_R_125_1">
               <sco>11111</sco>
               <serv-res>
                  <serv-res>ABC</serv-res>
               </serv-res>
               <cat>
                  <cate>CatA</cate>
               </cat>
               <o-ru-con>
                  <co-ru-con b-name="InterMge" bId="2">
                     <si-ru-con>
                        <ru-con-ite>
                           <ru-con-ite-lit>
                              <nae1>ac</nae1>
                              <ope>T_EQ</ope>
                              <val1>000</val1>
                           </ru-con-ite-lit>
                        </ru-con-ite>
                     </si-ru-con>
                     <si-ru-con>
                        <ru-con-ite>
                           <ru-con-ite-lit>
                              <nae1>ac</nae1>
                              <ope>T_EQ</ope>
                              <val1>001</val1>
                           </ru-con-ite-lit>
                        </ru-con-ite>
                     </si-ru-con>
                  </co-ru-con>
                  <co-ru-con b-name="InterMge" bId="3">
                     <si-ru-con>
                        <ru-con-ite>
                           <ru-con-ite-lit>
                              <nae1>tra</nae1>
                              <ope>T_EQ</ope>
                              <val1>014</val1>
                           </ru-con-ite-lit>
                        </ru-con-ite>
                     </si-ru-con>
                     <si-ru-con>
                        <ru-con-ite>
                           <ru-con-ite-lit>
                              <nae1>tra</nae1>
                              <ope>T_EQ</ope>
                              <val1>015</val1>
                           </ru-con-ite-lit>
                        </ru-con-ite>
                     </si-ru-con>
                  </co-ru-con>
               </o-ru-con>
               <al>true</al>
            </thres>
         </thress>
         <description> rSId=125 Fp=0.1234567 Dr=1.0 rSId=48 SFp=1.0 SDr=1.0_2012-10-10T09:55:09+02:00 </description>
      </cre-det-r>
      <cre-det-r> ....If this block exists, it will contain the same elements as above in the same order, otherwise, this block doesn't exists and the code contains only the preceding "cre-det-r" block. </cre-det-r>
   </rules>
</o-com-inter>
于 2012-10-12T08:20:19.960 回答