xslt-如何使用xslt过滤XML文档,保留给定元素,丢弃所有其他元素

xslt-如何使用xslt过滤XML文档,保留给定元素,丢弃所有其他元素,xml,xslt,xslt-1.0,Xml,Xslt,Xslt 1.0,我有以下xml: <?xml version="1.0" encoding="utf-8"?> <xml> <head> <name>This is my XML</name> <version>This is my XML</version> </head> <body> <item

我有以下xml:



    <?xml version="1.0" encoding="utf-8"?>
    <xml>
    <head>
        <name>This is my XML</name>
        <version>This is my XML</version>   
    </head>
    <body>
        <item id="SH2-99435">
            <properties>
                <property id="69">
                    <name>This is a property</name>
                    <amount>54.13</amount>
                    <estructure id="IZ4">
                        <name>caterpillar</name>
                        <location><zipCode>02210</zipCode><street>South Station</street></location>
                    </estructure>
                </property>
                <features id="ABC3">
                    <feature>If it works, a bug is another feature.</feature>
                    <feature>feature!!</feature>
                </features>
            </properties>
            <coding>
                <codename>Silent Hill 2</codename>
                <developer>Team Silent</developer>
                <publisher>Konami</publisher>
            </coding>
        </item>
        <item id="SH3-4498">
            <text value="it has values like the other item"/>
        </item>       
        <item id="MGS-2">
            <text value="it has values like the other item"/>
        </item>
    </body>
    </xml>


这是我的XML
这是我的XML
这是一处房产
54.13
毛虫
02210南站
如果它有效,bug就是另一个特性。
功能!!
寂静岭2
沉默队
科纳米
我想做到这一点:



    <?xml version="1.0" encoding="utf-8"?>
    <xml>
    <head>
        <name>This is my XML</name>
        <version>This is my XML</version>   
    </head>
    <body>
        <item>
            <properties>
                <property id="69">
                    <amount>54.13</amount>
                    <estructure id="IZ4">
                        <name>caterpillar</name>
                        <location><zipCode>02210</zipCode><street>South Station</street></location>
                    </estructure>
                </property>
            </properties>
        </item>
        <item id="SH3-4498">
            <text value="it should have properties and the selected sons"/>
        </item>       
        <item id="MGS-2" >
            <text value="it should have properties and the selected sons"/>
        </item>
    </body>   
    </xml>
    

这是我的XML
这是我的XML
54.13
毛虫
02210南站
我有这样的东西,可以正确过滤:



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

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

        <xsl:template match="xml/body/item/coding" />
        <xsl:template match="xml/body/item/properties/features" />
        <xsl:template match="xml/body/item/properties/property/name" />

    </xsl:stylesheet>


我被告知运行这个过滤器将产生10个文件,每个文件都有不同的标签;但是如果出现新的标记,我们必须更改10个文件以排除不需要的标记,而不是只在需要的文件上添加标记。例如,在另一个文件中,只包含编码,依此类推

我试过这个:

    

    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="some:ns">
        <xsl:output omit-xml-declaration="yes" indent="yes" />
        <xsl:strip-space elements="*" />
        <ns:WhiteList>
            <name>amount</name>
            <name>estructure</name>
        </ns:WhiteList>
        <xsl:template match="node()|@*">
            <xsl:copy>
                <xsl:apply-templates select="node()|@*" />
            </xsl:copy>
        </xsl:template>
        <xsl:template
            match="*[not(descendant-or-self::*[name()=document('')/*/ns:WhiteList/*])]" />
    </xsl:stylesheet>
    

数量
结构
但它没有复制Esstructure的子对象。 你知道我能做什么吗

谢谢


更新。添加了这样而不是相反的理由,以及更具描述性的问题。

我不接受这个答案,但在回答您的直接问题时,您正在测试作为estructure元素祖先(或自身)的元素,但您忽略了任何其他内容。这意味着结构的后代将被忽略。将xsl:if条件更改为以下内容

<xsl:if 
   test="descendant-or-self::*[generate-id(.)=$copyValue2]|ancestor::*[generate-id(.)=$copyValue2]">

恶心

老实说,您的第一个XSLT更好、更干净

如果您准确地解释了转换要遵循的规则,可能会有所帮助。如果规则是复制除某些节点之外的所有内容,那么您的第一个XSLT就非常适合这样做。如果规则是只复制显式节点,那么您可以提供更多关于需要复制哪些节点的详细信息,并且可以找到更好的方法

编辑:

作为对澄清的回应,请尝试以下XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="some:ns">
   <xsl:output omit-xml-declaration="yes" indent="yes"/>
   <xsl:strip-space elements="*"/>

   <ns:WhiteList>
      <name>amount</name>
      <name>estructure</name>
   </ns:WhiteList>

   <xsl:variable name="whistList" select="document('')/*/ns:WhiteList" />

   <xsl:template match="@*">
      <xsl:copy/>
   </xsl:template>   

   <xsl:template match="*">
      <xsl:if test="descendant-or-self::*[name()=$whistList/*]|ancestor::*[name()=$whistList/*]">
         <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
         </xsl:copy>
      </xsl:if>
   </xsl:template>      
</xsl:stylesheet>

数量
结构

我试图通过使用一个变量来保存文档查找,从而稍微整理一下它。请注意,使用xsl:if的原因是您不能在模板匹配中使用变量。

您最初的xsl看起来非常清晰!如果业务规则要复制除某些节点之外的所有内容,那么这就是一种方法。但有一点不一致,在您的初始XSL中,它排除了Esstructure节点,但这仍然存在于您的预期输出中。@TimC对此表示抱歉,我已修复了第一个包含Esstructure的xslt。我已更新了该问题以使其更清楚。我不知道它会被用作过滤器来生成更多的文件,直到有人告诉我这个解决方案可能非常复杂。非常感谢。它工作完美无瑕。不过,我注意到的一点是,它的运行速度比只列出排除标记要慢。这应该是因为比较。