【问题标题】:XSLT count() is not workingXSLT count() 不工作
【发布时间】:2011-03-24 19:32:17
【问题描述】:

我正在尝试计算 XML/Attributes/Attribute[@Type='ComplexAttr'] 的位置。如果存在,则执行此操作,否则执行其他操作。但是,计数始终为零。有人可以告诉我我错过了什么。 也有人可以指导我如何改进我使用很多的 xslt 的最后一部分 xsl:if 语句。 提前致谢。

XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:key name="type" match="Attribute" use="Type"/>
  <xsl:template match="/">
    <Data Schema="XML A">
      <xsl:apply-templates select="XML/Attributes/Attribute[generate-id() = generate-id(key('type', Type)[1])]">
        <xsl:sort select="Type" order="descending"/>
      </xsl:apply-templates>
      <errorCodes>
        <xsl:apply-templates select="XML/Attributes/Attribute" mode="errors"/>
      </errorCodes>
    </Data>
  </xsl:template>
  <xsl:template match="Attribute">
    <xsl:variable name="compType">
      <xsl:value-of select="count(XML/Attributes/Attribute[Type='ComplexAttr'])"/>
    </xsl:variable>  />
    <!--<xsl:value-of select="count($compType)"/>-->
    <xsl:if test="Type!='ComplexAttr'">
      <Attributes type="{Type}">
        <xsl:apply-templates select="key('type',Type)" mode="out"/>
        <xsl:if test="Type='common'">
          <Collection id="" name="test">
            <ComplexAttr refId="0">
              <MaskValue />
              <xsl:choose>
                <xsl:when test="$compType > 0">
                     <xsl:apply-templates select="key('type','ComplexAttr')" mode="out"/>
                </xsl:when>
                <xsl:otherwise>
                  <Attr id="" name="Color" value="000"/>
                  <Attr id="" name="Size" value="0010"/>
                  <Attr id="" name="UPC" value=""/>
                  <Attr id="" name="Style#" value=""/>
                  <Attr id="" name="Exclude" value=""/>
                </xsl:otherwise>
              </xsl:choose>
            </ComplexAttr>
          </Collection>
        </xsl:if>
      </Attributes>
    </xsl:if>
  </xsl:template>
  <xsl:template match="Attribute" mode="out">
    <Attr id="{id}" name="{Name}" value="{Value}"/>
  </xsl:template>
  <xsl:template match="Attribute[Type='ComplexAttr']" mode="out">
    <Attr id="{id}" name="{Name}" value="{Value}"/>
  </xsl:template>
  <xsl:template match="Attribute" mode="errors">
    <xsl:if test="Name['Buyer ID' or 'Coordinator ID' or 'Retail' or 
            'Master Pack Qty' or 'Master Pack Height' or 'Master Pack Length' or 'Master Pack Weight' or
            'Master Pack Width' or 'Product Description' or 'PO Cost' or 'GTIN' or 'Vendor Model'] and Value=''">
    <errorCode>"value for <xsl:value-of select="Name"/> is missing."</errorCode>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

示例 XML:

<?xml version="1.0" encoding="windows-1252"?>
<XML>
    <Attributes>
        <Attribute>
            <id>5</id>
            <Name>Buyer ID</Name>
            <Type>common</Type>
            <Value>Lee</Value>
        </Attribute>
        <Attribute>
            <id>331</id>
            <Name>Enviornment</Name>
            <Type>common</Type>
            <Value>Development</Value>
        </Attribute>
        <Attribute>
            <id>79</id>
            <Name>Retail</Name>
            <Type>common</Type>
            <Value></Value>
        </Attribute>
        <Attribute>
            <id>402</id>
            <Name>Gender</Name>
            <Type>category</Type>
            <Value>Men</Value>
        </Attribute>
    <Attribute>
         <id>1197</id> 
         <Name>UPC</Name> 
         <Type>ComplexAttr</Type> 
         <Value>Testing</Value> 
         <Path /> 
    </Attribute>
</Attributes>

输出: 如您所见,它没有给我预期的输出。它应该是 Attributes/Attribute[Type='common']/Collection/ComplexAttr/ 我得到以下

<?xml version="1.0" encoding="utf-8"?>
<Data Schema="XML A">
  <Attributes type="common">
    <Attr id="5" name="Buyer ID" value="Lee" />
    <Attr id="331" name="Enviornment" value="Development" />
    <Attr id="79" name="Retail" value="" />
    <Attr id="41" name="PlusShip" value="False" />
    <Collection id="" name="test">
      <ComplexAttr refId="0">
        <MaskValue />
        <Attr id="" name="Color" value="000" />
        <Attr id="" name="Size" value="0010" />
        <Attr id="" name="UPC" value="" />
        <Attr id="" name="Style#" value="" />
        <Attr id="" name="Exclude" value="" />
      </ComplexAttr>
    </Collection>
  </Attributes>
  <Attributes type="category">
    <Attr id="402" name="Gender" value="Men" />
    <Attr id="433" name="HeelHeight" value="" />
  </Attributes>
  <errorCodes>
    <errorCode>"value for Retail is missing."</errorCode>
  </errorCodes>
</Data>

【问题讨论】:

  • 您说“我正在尝试计算 XML/Attributes/Attribute[@Type='ComplexAttr'] 的位置。”我在您的示例中的任何地方都找不到该代码。
  • @Micheal Kay。根据与@Iwburk 的讨论,我正在更改我的代码。我已经上传了更新的 XSLT。如果你看到了什么,请告诉我。谢谢
  • @Michael - 对,但他确实有/XML/Attributes/Attribute[Type='ComplexAttr'],这就是我认为的意思
  • 我已经发布了一个更新的答案。希望这对您更有效。
  • 好问题,+1。有关问题的解释和简单的解决方案,请参阅我的答案。 :)

标签: xslt attributes count


【解决方案1】:
  <xsl:template match="Attribute">     
   <xsl:variable name="compType">       
     <xsl:value-of select="count(XML/Attributes/Attribute[Type='ComplexAttr'])"/>

   </xsl:variable>

问题就在这里

Attribute 元素没有名为 XML 的子元素,因此作为上述变量子元素的文本节点的值为“0”。

你想要

<xsl:variable name="compType" 
     select="count(/XML/Attributes/Attribute[Type='ComplexAttr'])"/>

说明:问题是由于使用了相对 XPath 表达式而不是绝对表达式。

【讨论】:

  • 感谢您的回复和解释问题。我做了这样的工作 这样做....。我仍然会接受您的回答,因为您指出了我所犯的错误并提供了正确的解决方案。谢谢
  • @JohnXsl:不客气。顺便说一句,建议尽可能避免使用//——这通常会导致性能下降。
  • 谢谢。我已按照您的建议进行了更改。
【解决方案2】:

但是,计数始终为零。能 有人告诉我我错过了什么。

答案#1:您正在计算具有名为Type 且值为ComplexAttr 的属性的Attribute 元素的数量:

<xsl:when test="count(//Attribute[@Type='ComplexAttr']) > 0">

但是您应该计算具有名为Type 的子元素的Attribute 元素的数量,其值为ComplexAttr

<xsl:when test="count(//Attribute[Type='ComplexAttr']) > 0">

仅对 XSLT 进行此更改会导致测试通过。

也有人可以指导我如何 改进 xslt 的最后一部分 我在哪里使用很多 xsl:if 声明。

答案#2:我会将这些条件中的每一个合并为一个:

<xsl:if test="Name['Retail' or 'Environment' or 
    'Master Pack Qty' or 'Master Pack Height'] and Value=''">
    <errorCode>"value for <xsl:value-of select="Name"/> is missing."</errorCode>
</xsl:if>

每种情况的处理方式相同,因此无需将它们分开。

这个简化的样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:key name="type" match="Attribute" use="Type"/>
  <xsl:template match="/">
      <xsl:apply-templates />
  </xsl:template>
  <xsl:template match="Attribute">
      <xsl:if test="Name['Buyer ID' or 'Coordinator ID' or 'Retail' or 
            'Master Pack Qty' or 'Master Pack Height' or 'Master Pack Length' or
            'Master Pack Weight' or 'Master Pack Width' or 'Product Description' or 
            'PO Cost' or 'GTIN' or 'Vendor Model'] and Value=''">
          <errorCode>"value for <xsl:value-of select="Name"/> is missing."</errorCode>
      </xsl:if>
  </xsl:template>
</xsl:stylesheet>

产生以下输出(根据您的输入):

<errorCode>"value for Retail is missing."</errorCode>

【讨论】:

  • @Iwburk 感谢您的回复。单独上述可能有效,但如果我将它插入 xslt,它仍然会评估所有元素并为非必需元素生成列表。但是,如果我这样做(Name='Buyer ID' or Name='Coordinator ID' or Name='Retail' ... or Name='Vendor Model')并且 Value=''")那么它工作正常。谢谢
【解决方案3】:

您无需计算:key('type','ComplexAttr') 为您提供所需的 Attribute 元素,其中 Type 子元素等于 'ComplexAttr',因为 xsl:key 声明。

如果你想在没有Attribute的情况下输出一些默认元素,那么使用:

<xsl:template match="Attribute[Type='ComplexAttr']"/>
<xsl:template match="Attribute[Type='common']">
    <Attributes type="common">
        <xsl:apply-templates select="key('type','common')" mode="out"/>
        <Collection id="" name="test">
            <ComplexAttr refId="0">
                <MaskValue />
                <xsl:apply-templates select="key('type','ComplexAttr')"
                                     mode="out"/>
            </ComplexAttr>
        </Collection>
    </Attributes>
</xsl:template>
<xsl:template match="Attribute[Type='common']
                              [not(key('type','ComplexAttr'))]"
              priority="1">
    <Attributes type="common">
        <xsl:apply-templates select="key('type','common')" mode="out"/>
        <Collection id="" name="test">
            <ComplexAttr refId="0">
                <MaskValue />
                    <Attr id="" name="Color" value="000"/>
                    <Attr id="" name="Size" value="0010"/>
                    <Attr id="" name="UPC" value=""/>
                    <Attr id="" name="Style#" value=""/>
                    <Attr id="" name="Exclude" value=""/>
            </ComplexAttr>
        </Collection>
    </Attributes>
</xsl:template>
<xsl:template match="Attribute">
    <Attributes type="{Type}">
        <xsl:apply-templates select="key('type',Type)" mode="out"/>
    </Attributes>
</xsl:template>

注意@priority 不依赖恢复机制。只是为了好玩,更拉风。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-03
    相关资源
    最近更新 更多