【问题标题】:Removing duplicate XML nodes in XSLT在 XSLT 中删除重复的 XML 节点
【发布时间】:2020-05-30 10:59:08
【问题描述】:

如果有人可以帮助我创建 xslt 以从 XML 中删除重复节点,我将不胜感激 基于重复元素的值(PlayBack--ControlInfo-ControlName)。

我想从 GStep/Step 中删除所有重复的元素(PlayBack--ControlInfo-ControlName)

输入 XML

<?xml version="1.0" encoding="utf-8"?>
      <Document>
       <Meta>
         <GpsFile>notepad_may_30_file</GpsFile>
         <GpsId>36fa4fe8-9691-4a7f-8bc1-9543f6b7d29a</GpsId>
          <ExePath>
             <ExePath1>C:\WINDOWS\SYSTEM32\notepad.exe</ExePath1>
          </ExePath>
        </Meta>
         <Process>
            <GStep DialogName="Untitled - Notepad">
             <Step DialogName="Untitled - Notepad">
              <Step-ID>3</Step-ID>     
              <PlayBack--ControlInfo-ControlName />      
            </Step>
            <Step DialogName="Untitled - Notepad">
              <Step-ID>4</Step-ID>     
              <PlayBack--ControlInfo-ControlName />     
            </Step>
            <Step DialogName="Untitled - Notepad">
              <Step-ID>5</Step-ID>      
              <PlayBack--ControlInfo-ControlName>Edit</PlayBack--ControlInfo-ControlName>     
            </Step>
            <Step DialogName="Untitled - Notepad">
              <Step-ID>6</Step-ID>      
              <PlayBack--ControlInfo-ControlName>Replace...\tCtrl+H</PlayBack--ControlInfo-ControlName>     
            </Step>
            <Step DialogName="Untitled - Notepad">
              <Step-ID>12</Step-ID>     
              <PlayBack--ControlInfo-ControlName />     
            </Step>
            <Step DialogName="Untitled - Notepad">
              <Step-ID>13</Step-ID>     
              <PlayBack--ControlInfo-ControlName>Edit</PlayBack--ControlInfo-ControlName>      
            </Step>
            <Step DialogName="Untitled - Notepad">
              <Step-ID>14</Step-ID>      
              <PlayBack--ControlInfo-ControlName>Replace...\tCtrl+H</PlayBack--ControlInfo-ControlName>      
            </Step>
            <Step DialogName="Untitled - Notepad">
              <Step-ID>15</Step-ID>     
              <PlayBack--ControlInfo-ControlName>Cancel</PlayBack--ControlInfo-ControlName>
            </Step>
          </GStep>
          <GStep DialogName="Replace">
             <Step DialogName="Replace">
                <Step-ID>8</Step-ID>     
                <PlayBack--ControlInfo-ControlName />      
             </Step>
             <Step DialogName="Replace">
                <Step-ID>9</Step-ID>      
                <PlayBack--ControlInfo-ControlName>Cancel</PlayBack--ControlInfo-ControlName>     
             </Step>
             <Step DialogName="Replace">
                <Step-ID>10</Step-ID>      
                <PlayBack--ControlInfo-ControlName />     
             </Step>
             <Step DialogName="Replace">
                <Step-ID>16</Step-ID>     
                <PlayBack--ControlInfo-ControlName />     
             </Step>
           </GStep>
         </Process>
       </Document>

实际上期待如下结果。

 <?xml version="1.0" encoding="utf-8"?>
       <Document>
         <Meta>
           <GpsFile>notepad_may_30_file</GpsFile>
           <GpsId>36fa4fe8-9691-4a7f-8bc1-9543f6b7d29a</GpsId>
           <ExePath>
              <ExePath1>C:\WINDOWS\SYSTEM32\notepad.exe</ExePath1>
          </ExePath>
        </Meta>
        <Process>
              <GStep DialogName="Untitled - Notepad">
              <Step DialogName="Untitled - Notepad">
                 <Step-ID>3</Step-ID>     
                 <PlayBack--ControlInfo-ControlName />      
              </Step>
              <Step DialogName="Untitled - Notepad">
                   <Step-ID>5</Step-ID>      
                   <PlayBack--ControlInfo-ControlName>Edit</PlayBack--ControlInfo-ControlName>     
              </Step>
             <Step DialogName="Untitled - Notepad">
                  <Step-ID>6</Step-ID>      
                  <PlayBack--ControlInfo-ControlName>Replace...\tCtrl+H</PlayBack--ControlInfo- 
                      ControlName>     
            </Step>
            <Step DialogName="Untitled - Notepad">
                 <Step-ID>15</Step-ID>     
                 <PlayBack--ControlInfo-ControlName>Cancel</PlayBack--ControlInfo-ControlName>
             </Step>
        </GStep>
       <GStep DialogName="Replace">
             <Step DialogName="Replace">
              <Step-ID>8</Step-ID>     
              <PlayBack--ControlInfo-ControlName />      
            </Step>
            <Step DialogName="Replace">
                <Step-ID>9</Step-ID>      
                <PlayBack--ControlInfo-ControlName>Cancel</PlayBack--ControlInfo-ControlName>     
            </Step>         
         </GStep>
     </Process>
   </Document>

我尝试使用下面的 xslt 代码 sn-p。

  <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="ControlNameInfo" match="Step" use="PlayBack--ControlInfo-ControlName"/>
     <xsl:template match="node()|@*">
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>
   <xsl:template match="GStep/Step[not(generate-id() = generate-id(key('ControlNameInfo', PlayBack-- 
        ControlInfo-ControlName)[1]))]"/>
        </xsl:stylesheet>

  Can anyone help 
  Thanks very much.

【问题讨论】:

    标签: xslt xslt-grouping


    【解决方案1】:

    为了在每个 GStep 中仅保留不同的 Step 节点,您必须在键中包含父 GStep。试试:

    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:strip-space elements="*"/>
    
    <xsl:key name="k1" match="Step" use="concat(PlayBack--ControlInfo-ControlName, '|', generate-id(..))"/>
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="GStep">
        <xsl:copy>
            <xsl:apply-templates select="Step[generate-id()=generate-id(key('k1', concat(PlayBack--ControlInfo-ControlName, '|', generate-id(..)))[1])]"/>
        </xsl:copy>
    </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

    • 感谢您的回复。它的工作但它没有为 GSteps 添加 DialogName="Replace" .. 例外 但结果得到:
    • @VikasMutagi 如果-看起来-GStep 中的所有Steps 具有相同的DialogName,您可以在模板匹配中的xsl:apply-templates 指令之前添加&lt;xsl:copy-of select="Step/@DialogName"/&gt; GStep。否则单独问这个问题,因为它与删除重复节点无关。
    • 嗨 michael.hor257k 我有一个小问题。如何添加不应删除空播放的条件--ControlInfo-ControlName
    • 它不会删除空的PlayBack--ControlInfo-ControlName s。它会删除重复的Steps。如果你想要别的东西,那么我建议你发布一个新问题。
    • 我只是想知道条件。它不应该删除任何空的PlayBack--ControlInfo-ControlName
    【解决方案2】:

    您还可以在 XSLT 2.0 中使用 group-by 方法。

    XSLT 2.0:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">    
        <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
        <xsl:strip-space elements="*"/>
    
        <!-- identity transform -->
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <!-- Remove duplicates -->
        <xsl:template match="GStep">
            <xsl:copy>
                <xsl:apply-templates select="@*"/>
                <xsl:for-each-group select="Step" group-by="PlayBack--ControlInfo-ControlName">
                    <xsl:sequence select="."/>
                </xsl:for-each-group>
            </xsl:copy>
        </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

      猜你喜欢
      • 2010-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多