【问题标题】:After removing double entries I also lost some other elements删除重复条目后,我还丢失了一些其他元素
【发布时间】:2015-09-16 14:27:47
【问题描述】:

我有一个非常大的 xml 文件。我尝试生成一个 leigther xml 文件,以便在使用 SSIS 提取数据时使用它。

我的文件包含几个案例。我把每个案例here

我提取了 4 个我简化的案例

 <ICECAT-interface xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://data.icecat.biz/xsd/files.index.xsd">
 <files.index Generated="20150916022750">
  <file path="export/freexml.int/FR/29799266.xml" Product_ID="29799266" Updated="20150915223003" Quality="ICECAT" Supplier_id="25" Prod_ID="89811499" Catid="827" On_Market="0" Model_Name="AmazonLED" Product_View="0" HighPic="http://images.icecat.biz/img/gallery/29799266_6440.jpg" HighPicSize="189800" HighPicWidth="2000" HighPicHeight="2000" Date_Added="20150915000000"></file>
 <file path="export/freexml.int/FR/4312841.xml" Product_ID="4312841" Updated="20150523100119" Quality="ICECAT" Supplier_id="30" Prod_ID="003R92156" Catid="197" On_Market="1" Model_Name="3640" Product_View="32767" HighPic="http://images.icecat.biz/img/norm/high/4312841-1574.jpg" HighPicSize="289900" HighPicWidth="1552" HighPicHeight="1200" Date_Added="20100306000000">
  <M_Prod_ID>DOCUMATE 3640</M_Prod_ID>
  <M_Prod_ID>003R92156</M_Prod_ID>
</file>
 <file path="export/freexml.int/FR/26064804.xml" Product_ID="26064804" Updated="20150827060248" Quality="ICECAT" Supplier_id="11077" Prod_ID="30097568" Catid="2943" On_Market="0" Model_Name="Color Show 110 Urban Coral" Product_View="2819" HighPic="http://images.icecat.biz/img/norm/high/26064804-6070.jpg" HighPicSize="34989" HighPicWidth="400" HighPicHeight="355" Date_Added="20150127000000">
      <M_Prod_ID>0000030097568</M_Prod_ID>
      <M_Prod_ID>0000030097568</M_Prod_ID>
</file>
<file path="export/freexml.int/FR/4312841.xml" Product_ID="4312841" Updated="20150523100119" Quality="ICECAT" Supplier_id="30" Prod_ID="dfqsdfqfq6" Catid="197" On_Market="1" Model_Name="3640" Product_View="32767" HighPic="http://images.icecat.biz/img/norm/high/4312841-1574.jpg" HighPicSize="289900" HighPicWidth="1552" HighPicHeight="1200" Date_Added="20100306000000">
  <M_Prod_ID Supplier_id="670" Supplier_name="Visioneer">dfqsdfqfq6</M_Prod_ID>
</file>
</files.index>
</ICECAT-interface>

我的 xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output  method="xml" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="ICECAT-interface">
    <xsl:apply-templates select="files.index"/>
</xsl:template>

<xsl:template match="files.index">
    <xsl:element name="files">
        <xsl:attribute name="Generated">
            <xsl:value-of select="@Generated"/>
        </xsl:attribute>
        <xsl:apply-templates select="file"/>
    </xsl:element>

</xsl:template>

<xsl:template match="file">
    <xsl:element name="file">
        <xsl:attribute name="path">
            <xsl:value-of select="@path"/>
        </xsl:attribute>
        <xsl:attribute name="Prod_ID">
            <xsl:value-of select="@Prod_ID"/>
        </xsl:attribute>
        <xsl:attribute name="Supplier_id">
            <xsl:value-of select="@Supplier_id"/>
        </xsl:attribute>
        <xsl:attribute name="Catid">
            <xsl:value-of select="@Catid"/>
        </xsl:attribute>
        <xsl:attribute name="Updated">
            <xsl:value-of select="@Updated"/>
        </xsl:attribute>
        <xsl:attribute name="Quality">
            <xsl:value-of select="@Quality"/>
        </xsl:attribute>
    </xsl:element>
    <xsl:apply-templates select="M_Prod_ID"/>
</xsl:template>

<xsl:template match="M_Prod_ID" />

<xsl:template match="M_Prod_ID[not(. = ../@Prod_ID)]">
    <file path="{../@path}" Prod_ID="{.}" Catid="../@Catid" Updated="../@Updated" Quality="../@Quality">

        <xsl:attribute name="Supplier_id">
            <xsl:choose>
                <xsl:when test="@Supplier_id">
                    <xsl:value-of select="@Supplier_id"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="../@Supplier_id"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:attribute>
    </file>

</xsl:template>

</xsl:stylesheet>

结果

 <files Generated="20150916022750">
  <file path="export/freexml.int/FR/29799266.xml"
     Prod_ID="89811499"
     Supplier_id="25"
     Catid="827"
     Updated="20150915223003"
     Quality="ICECAT"/>
  <file path="export/freexml.int/FR/4312841.xml"
     Prod_ID="003R92156"
     Supplier_id="30"
     Catid="197"
     Updated="20150523100119"
     Quality="ICECAT"/>
   <file path="export/freexml.int/FR/4312841.xml"
     Prod_ID="DOCUMATE 3640"
     Catid="../@Catid"
     Updated="../@Updated"
     Quality="../@Quality"
     Supplier_id="30"/>
   <file path="export/freexml.int/FR/26064804.xml"
     Prod_ID="30097568"
     Supplier_id="11077"
     Catid="2943"
     Updated="20150827060248"
     Quality="ICECAT"/>
   <file path="export/freexml.int/FR/26064804.xml"
     Prod_ID="0000030097568"
     Catid="../@Catid"
     Updated="../@Updated"
     Quality="../@Quality"
     Supplier_id="11077"/>
  <file path="export/freexml.int/FR/26064804.xml"
     Prod_ID="0000030097568"
     Catid="../@Catid"
     Updated="../@Updated"
     Quality="../@Quality"
     Supplier_id="11077"/>
  <file path="export/freexml.int/FR/4312841.xml"
     Prod_ID="dfqsdfqfq6"
     Supplier_id="30"
     Catid="197"
     Updated="20150523100119"
     Quality="ICECAT"/>
  </files>

这两个问题是

<file path="export/freexml.int/FR/26064804.xml"
     Prod_ID="0000030097568"
     Catid="../@Catid"
     Updated="../@Updated"
     Quality="../@Quality"
     Supplier_id="11077"/>

重复两次。

最后一行与 Supplier_Id=670 不重复

在前面的问题中。 @Abel 说使用

 <xsl:template match="M_Prod_ID[text() = following-sibling::M_Prod_ID/text()]">

结果here

然后文件节点重复两次没关系,但我丢失了文件节点

<file path="export/freexml.int/FR/4312841.xml"
     Prod_ID="DOCUMATE 3640"
     Catid="../@Catid"
     Updated="../@Updated"
     Quality="../@Quality"
     Supplier_id="30"/>

如何混合这两种解决方案? 其他人说使用分组。但我不知道我的情况如何。

更新

我想要

<files Generated="20150916022750">
  <file path="export/freexml.int/FR/29799266.xml"
     Prod_ID="89811499"
     Supplier_id="25"
     Catid="827"
     Updated="20150915223003"
     Quality="ICECAT"/>
   <file path="export/freexml.int/FR/4312841.xml"
     Prod_ID="003R92156"
     Supplier_id="30"
     Catid="197"
     Updated="20150523100119"
     Quality="ICECAT"/>
  <file path="export/freexml.int/FR/4312841.xml"
     Prod_ID="DOCUMATE 3640"
     Catid="../@Catid"
     Updated="../@Updated"
     Quality="../@Quality"
     Supplier_id="30"/>
  <file path="export/freexml.int/FR/26064804.xml"
     Prod_ID="30097568"
     Supplier_id="11077"
     Catid="2943"
     Updated="20150827060248"
     Quality="ICECAT"/>
  <file path="export/freexml.int/FR/26064804.xml"
     Prod_ID="0000030097568"
     Catid="../@Catid"
     Updated="../@Updated"
     Quality="../@Quality"
     Supplier_id="11077"/>
   <file path="export/freexml.int/FR/4312841.xml"
     Prod_ID="dfqsdfqfq6"
     Supplier_id="30"
     Catid="197"
     Updated="20150523100119"
     Quality="ICECAT"/>
   <file path="export/freexml.int/FR/4312841.xml"
     Prod_ID="dfqsdfqfq6"
     Supplier_id="670"
     Catid="197"
     Updated="20150523100119"
     Quality="ICECAT"/>
</files>

【问题讨论】:

  • 正如迈克尔在另一个问题中建议的那样,花点时间创建一个minimal reproducible example。你这样做了(除了最小的),你粘贴了一个链接很好,它有助于我们理解,但该链接将是临时的。因此,请同时在问题中粘贴证明您的问题的最小集合。另外,把你想要的显示为正确的输出,文本“I lost a node with X”不够清晰(否则我们最终会再次进行这么长时间的讨论......;)。
  • 我插入我的代码。这对我来说是最小值(我删除了很多未使用的字段,并且在更多 4 000 000 上只占用 4 行)然后我添加了我想要的结果。我希望它现在好吗?
  • 是的,绝对好多更好!现在至少你想要什么已经很清楚了(还没有测试过,但我想你已经做过了)。

标签: xml xslt xslt-grouping


【解决方案1】:

现在您想要什么变得很清楚,我认为解决方案比您第一次发布问题时看起来更容易。非常感谢您提供相关代码。

这段代码

 <xsl:template match="M_Prod_ID[text() = following-sibling::M_Prod_ID/text()]">

正在测试两个兄弟 M_Prod_ID 之间的重复,但它没有假设这些也可能出现一次。

XSLT 1.0 中的解决方案并不像人们想象的那么简单,它说明了为什么 Michael 建议使用 Muenchian 分组。这是非孟奇的方式:

<xsl:template match="M_Prod_ID[not(. = ../@Prod_ID)][following-sibling::M_Prod_ID][text() = following-sibling::M_Prod_ID/text()]" priority="5"/>

它适用于您的样式表的简化版本:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="ICECAT-interface">
        <xsl:apply-templates select="files.index"/>
    </xsl:template>

    <xsl:template match="files.index">
        <files Generated="{@Generated}">
            <xsl:apply-templates select="file"/>
        </files>    
    </xsl:template>

    <xsl:template match="file">
        <file path="{@path}" Prod_ID="{@Prod_ID}" Supplier_id="{@Supplier_id}" Catid="{@Catid}" Updated="{@Updated}" Quality="{@Quality}"/>
        <xsl:apply-templates select="M_Prod_ID"/>
    </xsl:template>

    <xsl:template match="M_Prod_ID"/>

    <xsl:template match="M_Prod_ID[not(. = ../@Prod_ID)][following-sibling::M_Prod_ID][text() = following-sibling::M_Prod_ID/text()]" priority="5"/>

    <xsl:template match="M_Prod_ID[not(. = ../@Prod_ID)]">
        <file path="{../@path}" Prod_ID="{.}" Catid="../@Catid" Updated="../@Updated" Quality="../@Quality">
            <xsl:copy-of select="parent::*[not(current()/@Supplier_id)]/@Supplier_id | @Supplier_id" />
        </file>
    </xsl:template>

</xsl:stylesheet>

这个转换的结果如下,和你的结果差不多,因为有些业务规则没有解释(主要是最后一个文件,但我相信你可以解决)。

<files Generated="20150916022750">
  <file path="export/freexml.int/FR/29799266.xml" Prod_ID="89811499" Supplier_id="25" Catid="827" Updated="20150915223003" Quality="ICECAT" />
  <file path="export/freexml.int/FR/4312841.xml" Prod_ID="003R92156" Supplier_id="30" Catid="197" Updated="20150523100119" Quality="ICECAT" />
  <file path="export/freexml.int/FR/4312841.xml" Prod_ID="DOCUMATE 3640" Catid="197" Updated="20150523100119" Quality="ICECAT" />
  <file path="export/freexml.int/FR/26064804.xml" Prod_ID="30097568" Supplier_id="11077" Catid="2943" Updated="20150827060248" Quality="ICECAT" />
  <file path="export/freexml.int/FR/26064804.xml" Prod_ID="0000030097568" Catid="2943" Updated="20150827060248" Quality="ICECAT" />
  <file path="export/freexml.int/FR/4312841.xml" Prod_ID="dfqsdfqfq6" Supplier_id="30" Catid="197" Updated="20150523100119" Quality="ICECAT" />
</files>

在您的原始帖子中,您将此作为某些属性的所需结果。

 Catid="../@Catid"
 Updated="../@Updated"
 Quality="../@Quality"

我认为这是不正确的,并将它们变成了 AVT。

作为赠品,这就是我如何将您的样式表从使用 xsl:attribute 转换为 AVT 语法(使用 XSLT 3.0,但可以很容易地被 XSLT 1.0 采用):

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

    <xsl:mode on-no-match="shallow-copy" />

    <xsl:template match="xsl:element">
        <xsl:element name="{@name}">
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>

    <xsl:template match="xsl:element/xsl:attribute">
        <xsl:attribute name="{@name}" select="'{'||xsl:value-of/@select||'}'"/>        
    </xsl:template>

    <xsl:template match="xsl:element/text()[not(normalize-space(.))]" />

</xsl:stylesheet>

【讨论】:

  • 哇!!!!完美...你能解释一下为什么你把' ' 因为我很高兴它工作,但如果我能理解更多 xslt ...
  • @YannickIngenierie,给我一点时间,我会更新。当人们要求解释代码时,我总是喜欢它:)。 PS:在 cmets 中引用代码时,应该使用反引号 `code here`,这样会使其(一点点)更具可读性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 2012-03-13
相关资源
最近更新 更多