【问题标题】:Issue with processing XSLT having multiple conditions处理具有多个条件的 XSLT 的问题
【发布时间】:2012-04-24 10:36:30
【问题描述】:

我的输入 XML 具有以下结构:

<catalog>
<cd>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
    <attributes>
        <attribute>
            <key>1</key>
            <value>one</value>
        </attribute>
        <attribute>
            <key>2</key>
            <value>two</value>
        </attribute>
    </attributes>
</cd>
<cd>
    <title>Hide your heart</title>
    <artist>Bonnie Tyler</artist>
    <country>UK</country>
    <company>CBS Records</company>
    <price>9.90</price>
    <year>1988</year>
    <attributes>
        <attribute>
            <key>1</key>
            <value>one</value>
        </attribute>
        <attribute>
            <key>2</key>
            <value>two</value>
        </attribute>
    </attributes>
</cd>
<cd>
    <title>Greatest Hits</title>
    <artist>Dolly Parton</artist>
    <country>USA</country>
    <company>RCA</company>
    <price>9.90</price>
    <year>1982</year>
    <attributes>
        <attribute>
            <key>1</key>
            <value>one</value>
        </attribute>
        <attribute>
            <key>2</key>
            <value>two</value>
        </attribute>
    </attributes>
</cd>
<cd>
    <title>Still got the blues</title>
    <artist>Gary Moore</artist>
    <country>UK</country>
    <company>Virgin records</company>
    <price>10.20</price>
    <year>1990</year>
    <attributes>
        <attribute>
            <key>1</key>
            <value>WON</value>
        </attribute>
        <attribute>
            <key>2</key>
            <value>two</value>
        </attribute>
    </attributes>
</cd>   
</catalog>

现在,我试图通过仅选择 { key = 1 和 value = WON } 的那些 cd 节点(与该键节点同级的值节点)来创建不同的 xml。一直坚持这一点,试图应用多个条件。尝试了以下方法:

  1. 尝试复制符合条件的节点
  2. 进行身份复制并忽略那些不符合条件的节点

不确定这是否可行,或者我做错了什么。这是我的 xslt 的样子:

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

<xsl:variable name="KeyToBeMatched">1</xsl:variable>
<xsl:param name="ValueToBeMatched">WON</xsl:param>


<xsl:template match="catalog">

      <xsl:for-each select="cd">
        <xsl:for-each select="attributes/attribute[keu = $KeyToBeMatched]">
            <xsl:variable name="attributeValue" select="value"/>
                <xsl:if test="$attributeValue = $RMGAccountId"> 
                        <xsl:copy>
                            <xsl:apply-templates select="@*|*|text()" />
                        </xsl:copy>
                </xsl:if>
        </xsl:for-each>
      </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

【问题讨论】:

    标签: xml xslt multiple-conditions


    【解决方案1】:

    我不确定您是否要复制整个 cd 元素是否应该具有匹配的属性,但如果您这样做了,您可以简单地添加一个这样的匹配模板,您可以在其中然后添加代码来复制元素

    <xsl:template match="cd[attributes/attribute[key='1'][value='WON']]">
        <!-- Copy element -->
    </xsl:template>
    

    然后可以匹配和忽略其他 cd 元素

    <xsl:template match="cd" />
    

    试试这个 XSLT:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
       <xsl:output method="xml" indent="yes"/>
    
       <xsl:template match="cd[attributes/attribute[key='1'][value='WON']]">
          <xsl:call-template name="identity" />
       </xsl:template>
    
       <xsl:template match="cd" />
    
       <xsl:template match="@*|node()" name="identity">
          <xsl:copy>
             <xsl:apply-templates select="@*|node()"/>
          </xsl:copy>
       </xsl:template>
    </xsl:stylesheet>
    

    当应用于您的示例 XML 时,输出了已故伟大的 Gary Moore

    <catalog>
       <cd>
          <title>Still got the blues</title>
          <artist>Gary Moore</artist>
          <country>UK</country>
          <company>Virgin records</company>
          <price>10.20</price>
          <year>1990</year>
          <attributes>
             <attribute>
                <key>1</key>
                <value>WON</value>
             </attribute>
             <attribute>
                <key>2</key>
                <value>two</value>
             </attribute>
          </attributes>
       </cd>
    </catalog>
    

    当然,在您的情况下,您需要参数化匹配值,在这种情况下您不能使用这种方法,因为在模板匹配中不能使用变量。相反,您可以使用 xsl:for-each 来匹配 cd 元素:

    <xsl:for-each select="cd[attributes/attribute[key=$KeyToBeMatched][value=$ValueToBeMatched]]">
    

    这是此方法的完整 XSLT

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
       <xsl:output method="xml" indent="yes"/>
    
       <xsl:variable name="KeyToBeMatched">1</xsl:variable>
       <xsl:param name="ValueToBeMatched">WON</xsl:param>
    
       <xsl:template match="catalog">
          <xsl:for-each select="cd[attributes/attribute[key=$KeyToBeMatched][value=$ValueToBeMatched]]">
             <xsl:call-template name="identity"/>
          </xsl:for-each>
       </xsl:template>
       <xsl:template match="@*|node()" name="identity">
          <xsl:copy>
             <xsl:apply-templates select="@*|node()"/>
          </xsl:copy>
       </xsl:template>
    </xsl:stylesheet>
    

    这也将返回令人敬畏的加里摩尔。

    【讨论】:

    • 一个相关问题:我在匹配表达式中使用的值需要动态传递。如果我放一个参数而不是硬编码的“WON”,那是不被接受的。有什么方法可以实现吗?
    • 啊,是的,你是对的。我已经扩展了我的答案,以展示在这种情况下如何使用参数。
    【解决方案2】:

    试试这个:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output  method="xml" indent="yes"/>
    
    <xsl:variable name="KeyToBeMatched">1</xsl:variable>
    <xsl:param name="ValueToBeMatched">WON</xsl:param>
    
    <xsl:template match="list"> 
        <xsl:for-each select="cd">
            <xsl:for-each select="attributes/attribute[key = $KeyToBeMatched]">
                <xsl:variable name="attributeValue" select="value"/>
                <xsl:if test="$attributeValue = $ValueToBeMatched"> 
                    <xsl:copy>
                        <xsl:apply-templates select="@*|*|text()" />
                    </xsl:copy>
                </xsl:if>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
    </xsl:stylesheet>
    

    从未声明过变量“RMGAccountId”,我将其与“ValueToBeMatched”进行了交换。并修复了Filype指出的错字。应用到你得到这个 XML 的源:

    <?xml version="1.0" encoding="UTF-8"?>
    <attribute> 1 WON </attribute>
    

    【讨论】:

      【解决方案3】:

      有错别字

      --------------------------------------------V---------------------
      <xsl:for-each select="attributes/attribute[keu = $KeyToBeMatched]">
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-06
        • 1970-01-01
        • 2018-06-19
        相关资源
        最近更新 更多