我有带有一定数量子元素的元素。子元素如下所示:
<checker val="this" some="yuppi" here="there" what="nothing"/>其中一些属性充当过滤器。我不知道哪一个和多少个提前。我必须在另一个文件中查找,该文件包含在特定时间用作筛选器的所有属性。该文件基本上如下所示:
<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的属性,也会发生同样的情况。
我目前的做法如下:
<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>现在,即使元素有一个属性,元素也会被复制到新文件中。
最好的编码方法是什么?
我希望我能解释我的问题..。
提前感谢您的提示和帮助!
编辑
一个希望更清楚的例子。
带有检查器元素的文件:
<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>查找文件:
<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>预期产出:
<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元素中,前两个检查器元素由于相同的规则被过滤掉。它们至少有一个作为筛选器指定的属性。
发布于 2015-04-24 14:56:12
我相信你需要这样的东西:
XSLT2.0
<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>注意:您的两个文件都必须有良好的格式才能工作;目前两者都不是。
https://stackoverflow.com/questions/29849509
复制相似问题