首页 > 解决方案 > XSLT:如果结果为真,则匹配字段字符串,然后复制完整的相应节点

问题描述

我是 XSLT 的新手。

我需要帮助和指导来完成以下任务

我有一个输入 xml:

<Prices>
<Price>
    <Name>1234</Name>
    <Type>account</Type>
    <group>shell</group>
    <Cost>0.23</Cost>

</Price>
<Price>
    <Name>1234</Name>
    <Type>account</Type>
    <group>shell</group>
    <Cost>0.23</Cost>

</Price>
<Price>
    <Name>test12345</Name>
    <Type>Data Stored - Tables</Type>
    <group>--</group>
    <Cost>0.00</Cost>

</Price>

我需要在每个元素中搜索 group ,例如在这种情况下是shell。一旦外壳匹配,完整的节点应该出现在输出 xml 中,例如

<Prices>
<Price>
    <Name>1234</Name>
    <Type>account</Type>
    <group>shell</group>
    <Cost>0.23</Cost>

</Price>
<Price>
    <Name>1234</Name>
    <Type>account</Type>
    <group>shell</group>
    <Cost>0.23</Cost>

</Price>
 </Prices>

我尝试使用很多 xslt,但无法获得此输出。

有人可以帮帮我吗。

在这里,输入文件只有 3 个节点,但实际上它也可以有超过 50 个节点。

尝试使用这个 xslt 但它失败了

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- Identity transform -->
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="@* | node()"> 
<xsl:copy> 
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:param name="str" select="'shell'"/>
<xsl:template match="@* | node()">
<output> 
<xsl:for-each select="//*[.=$str]">
<xsl:copy> 
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:for-each> 
</output> 
</xsl:template> 
</xsl:stylesheet>

感谢 Martin 帮助以前的用例。

现在我也希望这包括搜索两个或多个变量。为了理解,下面是xml输入文件

<Prices>

<Price>
<Name>1234</Name>
<Type>account</Type>
<group>shell</group>
<Cost>0.23</Cost>

</Price>

<Price>
<Name>1234</Name>
<Type>account</Type>
<group>shell</group>
<Cost>0.23</Cost>

</Price>

<Price>
<Name>test12345</Name>
<Type>Data Stored - Tables</Type>
<group>--</group>
<Cost>0.00</Cost>
</Price>

<Price>
<Name>1234</Name>
<Type>account</Type>
<group>shell12345</group>
<Cost>0.54</Cost>
</Price>

<Price>
<Name>1234</Name>
<Type>account</Type>
<group>nutshell1234</group>
<Cost>0.60</Cost>
</Price>

</Prices>

我希望输出是

<Prices>

<Price>
<Name>1234</Name>
<Type>account</Type>
<group>shell</group>
<Cost>0.23</Cost>

</Price>

<Price>
<Name>1234</Name>
<Type>account</Type>
<group>shell</group>
<Cost>0.23</Cost>

</Price>
<Price>
<Name>1234</Name>
<Type>account</Type>
<group>shell12345</group>
<Cost>0.54</Cost>
</Price>

<Price>
<Name>1234</Name>
<Type>account</Type>
<group>nutshell1234</group>
<Cost>0.60</Cost>
</Price>

</Prices>

此外,具有 sheel、nutshell、shell12345 的组也可能是不同的,也没有匹配任何字符串。但好的一点是我必须搜索的内容是否可用,因此如果需要,我们也可以提供硬编码值。

标签: xsltxslt-1.0xslt-2.0

解决方案


鉴于您从身份转换模板开始,我认为最简单的方法是为那些Price没有所需group值的元素添加一个空模板:

 <xsl:template match="Price[not(group = $str)]"/>

因为这样这些就不会被复制。

https://xsltfiddle.liberty-development.net/bdxtri的 XSLT 3 版本和在http://xsltransform.hikmatu.com/eiZQaET的 XSLT 2 版本在线。


推荐阅读