从xml

时间:2016-03-31 11:50:46

标签: xml xslt

我有一些相当大的xml文件,我需要删除特定的重复元素,最好使用xslt。 我尝试了here提供的解决方案,但没有任何运气。

输入xml可能如下所示

<workspace version="54">
<rootelement>
<description>Nice product</description>
<options>
<values>
.....
<values>
</options>
<product_structure>
<variable name="A">
<description>Feature A</description>
...
<language_translations>
<language_translation language="EN">Include big red button</language_translation>
<language_translation language="EN">Include big red button</language_translation>
<language_translation language="EN">Include big red button</language_translation>
<language_translation language="EN">Include big red button</language_translation>
<language_translation language="EN">Include big red button</language_translation>
<language_translation language="EN">Include big red button</language_translation>
....
</language_translations>
...

我想要实现的是每个“/ rootelement / product_structure / variable / language_translations”只有一个。 幸运的是,我只使用一种语言进行操作,因此语言属性将始终为“EN”

我目前正在使用Notepad ++中的XML Tools来应用xsl,但如果可以使用任何免费的命令行工具,我也愿意尝试。

对正确方向的任何帮助表示赞赏! :)

2 个答案:

答案 0 :(得分:0)

以下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" />

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

    <xsl:template match="language_translations/language_translation[1]" priority="2">
         <xsl:copy>
                <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="language_translations/language_translation">
    </xsl:template>

</xsl:stylesheet> 

当应用于此输入XML(我为了完整性和可读性而修改了一点)......

<workspace version="54">
    <rootelement>
        <description>Nice product</description>
        <options>
            <values>
.....
            </values>
        </options>
        <product_structure>
            <variable name="A">
                <description>Feature A</description>
...
                <language_translations>
                    <language_translation language="EN">Include big red button</language_translation>
                    <language_translation language="EN">Include big red button</language_translation>
                    <language_translation language="EN">Include big red button</language_translation>
                    <language_translation language="EN">Include big red button</language_translation>
                    <language_translation language="EN">Include big red button</language_translation>
                    <language_translation language="EN">Include big red button</language_translation>
....
                </language_translations>
            </variable>
        </product_structure>
    </rootelement>
</workspace>

它产生这个输出:

<?xml version="1.0" encoding="UTF-8"?><workspace version="54">
    <rootelement>
        <description>Nice product</description>
        <options>
            <values>
.....
            </values>
        </options>
        <product_structure>
            <variable name="A">
                <description>Feature A</description>
...
                <language_translations>
                    <language_translation language="EN">Include big red button</language_translation>





....
                </language_translations>
            </variable>
        </product_structure>
    </rootelement>
</workspace>

如果需要,我还可以提供一个考虑language属性的版本(仅删除重复的语言)。

默认情况下,XSLT会从输入中复制任何内容。如果它在language_translation中遇到language_translations元素,它会在最后调用空模板,导致无输出。但是,对于language_translation中的第一个 language_translations,上面的模板优先(注意优先级)。所以只有那一个被复制。

答案 1 :(得分:0)

因此,当我收到您的问题时,您希望消除在同一<language_translation>内包含相同文本的第2个,第3个等<language_translations>。我的方法是编写一个模板,如果存在具有相同文本值的前一个兄弟,则该模板不执行任何操作:

<xsl:template match="language_translation[text()=preceding-sibling::language_translation/text()]"/>
相关问题