2011-03-24 62 views
2

我正在嘗試計數XML /屬性/屬性[@ Type ='ComplexAttr']。如果它存在,那麼請做其他事情。但是,count總是零。有人可以告訴我錯過了什麼嗎? 也可以有人指導我如何改善xslt,我使用許多 xsl:if語句的最後部分。 在此先感謝。XSLT計數()不起作用

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> 

輸出: 正如你可以看到它是不是給我預期的輸出。它應該是屬性/屬性[類型=「普通」] /收藏/ 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> 
+0

你說:「我正在嘗試計算XML/Attributes/Attribute [@Type ='ComplexAttr']」。我無法在示例中的任何位置找到該代碼。 – 2011-03-24 21:45:47

+0

@Micheal Kay。根據我與@Iwburk的討論,我正在對代碼進行更改。我已經上傳了更新的XSLT。如果你看到什麼,請告訴我。謝謝 – JohnXsl 2011-03-24 22:16:45

+0

@Michael - 對,但他確實有'/ XML/Attributes/Attribute [Type ='ComplexAttr']'這是我的意思 – 2011-03-24 22:19:40

回答

4
<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表達式,而不是絕對的。

+0

感謝您的回覆並解釋了問題。我做了這樣的工作 0」> do this ....。我指出我犯的錯誤後仍然接受你的回答,提供了正確的解決方案謝謝 – JohnXsl 2011-03-25 13:49:34

+1

@JohnXsl:不用客氣,順便說一下,建議儘可能避免使用'//'',否則通常會導致性能低下。 – 2011-03-25 14:30:14

+0

謝謝。你的建議。 – JohnXsl 2011-03-25 15:42:04

1

然而,數始終爲零。可以 有人告訴我錯過了什麼。

答案#1:你就指望命名具有屬性Attribute元素的數量Type,其值是ComplexAttr

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

但是你應該對具有一個Attribute元素的數量子元素名爲Type其值爲ComplexAttr

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

僅對XSLT進行此更改會導致測試通過。

也可以有人指導我在哪裏我使用的許多XSL如何 提高XSLT 的最後一部分:如果 語句。

答案#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> 
+0

@Iwburk感謝您的回覆。單獨上述可能會起作用,但如果我將它插入xslt中,它仍然會評估所有元素併爲非必需元素生成列表。但是,如果我這樣做(名稱='買家ID'或名稱='協調員ID'或名稱='零售'...或名稱='供應商模式')和價值=''「),那麼它工作正常。 – JohnXsl 2011-03-25 03:37:58

0

你並不需要統計: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不依賴於恢復機制。只是爲了好玩,更拉風格。