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

 <xsl:key name="Part" match="parts/*" use="@id"/>
	<xsl:key name="PartNumber" match="parts/*/property[@name='PartNumber']" use="../@id"/>

	<xsl:template match="/">
		<BOM>

   <!--loop on all wire element-->
   <xsl:for-each select="parts/*[name()!='assembly']">

    <xsl:variable name="id" select="@id"/>
    
    <!--check if the wire element is used by the assembly elememt that follows-->
    <xsl:if test="count(following-sibling::assembly/assemblyelement[@ref=$id])=0">    
  
     <!--it is not... check if there are multiple occurance of this wire based on @id-->
     <!--in case of  multiple occurance we consider the first one-->
     <xsl:if test="generate-id(key('Part', @id)[1])=generate-id(.)">
      <xsl:copy>
      	<xsl:attribute name="partnumber"><xsl:value-of select="property[@name='PartNumber']/@val"/></xsl:attribute>
       <xsl:attribute name="quantity"><xsl:value-of select="count(key('Part', @id))"/></xsl:attribute>
      </xsl:copy>
     </xsl:if>
    </xsl:if>

   </xsl:for-each> 
   
			<xsl:apply-templates select="parts/assembly"/>
		</BOM>
	</xsl:template>

	<xsl:template match="assembly">

		<assembly>

			<!--build a list of PartNumber Names based on assemblyelement children-->
			<xsl:variable name="parts">
    <xsl:for-each select="assemblyelement">
     <xsl:for-each select="key('PartNumber', @ref)">
						<xsl:copy>
							<xsl:copy-of select="@val"/>
							<xsl:copy-of select="@name"/>
							
       <!-- 
        Let's copy the parent node as child so we can use it later on;
        may be we don't have only "wire"
       -->
							<xsl:for-each select="..">
								<xsl:copy/>
							</xsl:for-each>
						</xsl:copy>
					</xsl:for-each>
				</xsl:for-each>
			</xsl:variable>


			<!--Sort PartNumber by @val-->
			<xsl:variable name="OrderedParts">
				<xsl:for-each select="$parts/*">
					<xsl:sort select="@val"/>
					<xsl:copy-of select="."/>
				</xsl:for-each>
			</xsl:variable>


			<!-- Perform grouping and counting -->
			<xsl:for-each select="$OrderedParts/*">

				<xsl:variable name="current" select="@val"/>

				<xsl:if test="string(@val) != string( following-sibling::node()[1]/@val ) ">

					<xsl:variable name="count" select="count(preceding-sibling::node()[@val = $current])+1"/>
					<xsl:variable name="partnumber" select="@val"/>

					<xsl:for-each select="./node()[1]"><!--Now we can use the node we stored as child node-->
						<xsl:copy> 
							<xsl:attribute name="partnumber"><xsl:value-of select="$partnumber"/></xsl:attribute>
       <xsl:attribute name="quantity"><xsl:value-of select="$count"/></xsl:attribute>
						</xsl:copy>
					</xsl:for-each>
				</xsl:if>

			</xsl:for-each>
		</assembly>

	</xsl:template>
</xsl:stylesheet><!-- Stylus Studio meta-information - (c)1998-2004. Sonic Software Corporation. All rights reserved.
<metaInformation>
<scenarios ><scenario default="yes" name="Scenario1" userelativepaths="yes" externalpreview="no" url="wire.xml" htmlbaseurl="" outputurl="" processortype="saxon6" profilemode="0" profiledepth="" profilelength="" urlprofilexml="" commandline="" additionalpath="" additionalclasspath="" postprocessortype="none" postprocesscommandline="" postprocessadditionalpath="" postprocessgeneratedext=""/></scenarios><MapperMetaTag><MapperInfo srcSchemaPathIsRelative="yes" srcSchemaInterpretAsXML="no" destSchemaPath="" destSchemaRoot="" destSchemaPathIsRelative="yes" destSchemaInterpretAsXML="no" ><SourceSchema srcSchemaPath="wire.xml" srcSchemaRoot="parts" AssociatedInstance="" loaderFunction="document" loaderFunctionUsesURI="no"/></MapperInfo><MapperBlockPosition><template match="/"></template><template match="assembly"><block path="assembly/xsl:for&#x2D;each/xsl:if" x="408" y="54"/></template></MapperBlockPosition></MapperMetaTag>
</metaInformation>
-->