如何使用XSLT删除双重出现的兄弟节点

时间:2015-09-16 10:33:59

标签: xml xslt

我有一个包含某些产品的xml文件。这是一个非常大的文件。然后我创建一个xslt文件来构建另一个更轻松的xml文件。

<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>
  <EAN_UPCS>
    <EAN_UPC Value="0000030097568" />
  </EAN_UPCS>
</file>

这里是M_Prod为double的示例。 在这里我的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[not(. = ../@Prod_ID)]">
        <xsl:element name="file">
            <xsl:attribute name="path">
                <xsl:value-of select="../@path"/>
            </xsl:attribute>
            <xsl:attribute name="Prod_ID">
                <xsl:value-of select="."/>
            </xsl:attribute>
            <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>
            <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:template>

</xsl:stylesheet>

我看到的分组解决方案太多了,但我无法正确查看xslt文件。

更新1

Here my sample

看看有3个文件节点生成。我只想要两个第一个节点。

更新2

我想要

<files Generated="20150916022750">
   <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"
         Supplier_id="11077"
         Catid="2943"
         Updated="20150827060248"
         Quality="ICECAT"/></files>

1 个答案:

答案 0 :(得分:1)

根据讨论结论编辑了问题。

  

如何使用XSLT删除双重出现的兄弟节点

有几种方法可以做到这一点。首先,您可以使用Muenchian分组,但您已经说过,您发现它太复杂而无法掌握。那么让我们来看看另一种选择。

一种方法是将以下内容添加到当前样式表中:

<xsl:template match="M_Prod_ID[. = preceding-sibling::M_Prod_ID[1]]" />

您可能需要为模板添加优先级,因为如果您的其他M_Prod_ID保持原样,它们将具有相同的优先级,然后选择后者,否则将出现错误提出:

<xsl:template match="M_Prod_ID[. = preceding-sibling::M_Prod_ID[1]]" priority="10"/>

测试

通常最好在最小的上下文中查看某些内容,以了解其工作原理。因此,我已经获取了您的输入文件并针对以下简化的样式表运行它。 Please click here to see it in action on xsltransform.net

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

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

    <xsl:template match="M_Prod_ID[. = preceding-sibling::M_Prod_ID[1]]" />

</xsl:stylesheet>

导致以下输出(删除重复的M_Prod_ID

<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>

  <EAN_UPCS>
    <EAN_UPC Value="0000030097568" />
  </EAN_UPCS>
</file>

注释

您经常使用<xsl:attribute> <xsl:element>,但您也可以使用文字结果元素和属性值模板:

<file path="{../@path}" Prod_ID="{.}" .....>
    <!-- any child elements go here -->