首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XSLT2.0筛选出具有在不同文件中列出的某些属性的元素

XSLT2.0筛选出具有在不同文件中列出的某些属性的元素
EN

Stack Overflow用户
提问于 2015-04-24 14:00:37
回答 1查看 414关注 0票数 0

我有带有一定数量子元素的元素。子元素如下所示:

代码语言:javascript
复制
<checker val="this" some="yuppi" here="there" what="nothing"/>

其中一些属性充当过滤器。我不知道哪一个和多少个提前。我必须在另一个文件中查找,该文件包含在特定时间用作筛选器的所有属性。该文件基本上如下所示:

代码语言:javascript
复制
<someElem >
<f name="val" value="this"/>
<f name="other" value="that"/>
<f name="val" value="something"/>
</someElem>
<someElem >
<f name="val" value="this"/>
<f name="other" value="that"/>
<f name="some" value="yuppi"/>
</someElem>

因此,在不同的场合,不同的来源材料,可能有或多或少不同的过滤属性。

我知道要在查找文件中选择哪个元素,因为它具有与检查器-元素的父元素相同的id。基本上,检查器元素的父元素有一个应用过滤器,过滤掉某些检查器元素。

我最终想要实现的是:我有一个元素,它有很多检查器元素作为子元素,我只想将这些检查器元素复制到一个新文件中,该文件中没有在查找文件中列出的任何属性,即过滤器文件。

因此,在上面的示例中,检查器元素不会被复制到新文件中,因为它有一个val属性,而查找文件中的对应元素是第一个元素,并且它有一个名为val的f元素。这足以让我知道它应该被取消。如果检查器元素有一个名为other的属性,也会发生同样的情况。

我目前的做法如下:

代码语言:javascript
复制
        <xsl:for-each select="key('test', @id, $elemFile)">
            <xsl:if test="@id = $curID">
            <xsl:variable name="curElemID" select="@id"/>
                <xsl:for-each select="node()"> <!-- these here are the checker-elements from the example. They are child nodes of another element that I am iterating over -->
                <xsl:variable name="curElem" select="."/>
                    <xsl:for-each select="@*"> <!-- looking at each of the attributes of the checker-element -->
                    <xsl:choose>
                        <xsl:when test="$lookupfile//someElem[@id = $curElemID]//f/@name = local-name()"> <!-- check if the current checker-element has one of the attributes whose local-name is the same as the name-attribute value of the corresponding someElem element -->
                            <xsl:message>
                            <xsl:text>Hit </xsl:text><xsl:value-of select="$curElem/@id"/>
                            </xsl:message>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:copy-of select="$curElem"/>
                            </xsl:otherwise>
                            </xsl:choose>
                    </xsl:for-each>
                </xsl:for-each>
            </xsl:if>   
        </xsl:for-each>

现在,即使元素有一个属性,元素也会被复制到新文件中。

最好的编码方法是什么?

我希望我能解释我的问题..。

提前感谢您的提示和帮助!

编辑

一个希望更清楚的例子。

带有检查器元素的文件:

代码语言:javascript
复制
<root>
<abc id="someId">
<checker val="this" test="testest" here="there" what="nothing"/>
<checker some="yuppi" here="there" />
<checker other="that"/>
</abc>
<abc id="someOtherId">
<checker val="this" some="yuppi" here="there" what="nothing"/>
<checker some="yuppi" here="there" what="nothing"/>
<checker attr="val""/>
</abc>
</root>

查找文件:

代码语言:javascript
复制
<someElem id="someId"> <!-- filter that gets applied to the first abc element-->
<f name="val" value="this"/>
<f name="other" value="that"/>
<f name="val" value="something"/>
</someElem>
<someElem id="someOtherId"> <!-- filter that gets applied to the second abc element-->
<f name="other" value="that"/>
<f name="some" value="yuppi"/>
</someElem>

预期产出:

代码语言:javascript
复制
<new>
<abc id="someId">
<checker some="yuppi" here="there" />
</abc>
<abc id="someOtherId">
<checker attr="val""/>
</abc>
</new>

在第一个abc元素中,第一个检查器元素被过滤掉,因为在与abc元素具有相同id的someElem中,指定的过滤器是val和其他--第一个检查器元素具有一个名为val的属性。

第三个检查器元素被过滤掉,因为它有一个名为other的属性。

在第二个abc元素中,前两个检查器元素由于相同的规则被过滤掉。它们至少有一个作为筛选器指定的属性。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-24 14:56:12

我相信你需要这样的东西:

XSLT2.0

代码语言:javascript
复制
<xsl:stylesheet version="2.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:param name="lookupdoc" select="'path/to/your/other/file.xml'" />
<xsl:key name="f" match="f" use="../@id" />

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

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

<xsl:template match="abc">
    <xsl:variable name="x-names" select="key('f', @id, document($lookupdoc))/@name" />
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates select="checker[not(@*[name()=$x-names])]"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

注意:您的两个文件都必须有良好的格式才能工作;目前两者都不是。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29849509

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档