| Author |
mock question
|
jim yin
Ranch Hand
Joined: Aug 15, 2002
Posts: 111
|
|
How many <ItemName> elements will be there in output if the given XSL style sheet is applied on the given XML document? -------------------XML Document------------------- <?xml version="1.0"?> <ItemsList> <Items supplier="vinay"> <ItemName code="M1">Mouse</ItemName> <ItemName code="M2">Mouse</ItemName> <ItemName code="K1">KeyBoard</ItemName> </Items> <Items supplier="xyz"> <ItemName code="M1">Mouse</ItemName> <ItemName code="M2">KeyBoard</ItemName> <ItemName code="K2">KeyBoard</ItemName> <ItemName code="K1">KeyBoard</ItemName> </Items> </ItemsList> -------------------XSL Document---------------------- <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl  utput indent="yes" omit-xml-declaration="yes"/> <xsl:key name="kCodeValue" match="ItemName" use="concat(@code,'::', .)"/> <xsl:template match="/"> <ItemList> <xsl:apply-templates/> </ItemList> </xsl:template> <xsl:template match="text()"/> <xsl:template match="ItemName[count(.| key('kCodeValue',concat(@code,'::', .))[1])=1]"> <xsl:copy-of select="."/> </xsl:template> </xsl:stylesheet>
The answer is 5. I don't know how this comes out. Could anyone explain this? Thanks.
|
 |
jim yin
Ranch Hand
Joined: Aug 15, 2002
Posts: 111
|
|
|
This is a tough one, could Jayadev and Dan comment on this? Thanks.
|
 |
Jayadev Pulaparty
Ranch Hand
Joined: Mar 25, 2002
Posts: 645
|
|
Jim, First of all i should appreciate you getting really good questions on to the forum. I've not prepared the xsl:keys and need to do that; I was a little busy trying to write some code for the schema question put up today; I need to take some time to understand keys first and then may be will get into a position to answer this. So i look forward to hear from Dan or anybody on this forum for an answer to this.
|
 |
jim yin
Ranch Hand
Joined: Aug 15, 2002
Posts: 111
|
|
|
Javadev, you are doing very well in terms of understanding basic concepts. Well, this test covers too much ground, it is really hard to get deeper.
|
 |
Vasudha Deepak
Ranch Hand
Joined: Mar 15, 2002
Posts: 86
|
|
This code is retreiving elements for a unique combination of attribute and element value The data retreived is according to this pattern: M1mouse M2 mouse K1 keyboard M2 keyboard K2 keyboard Hence it gets a count of only 5 elements.
|
IBM Certified Developer -XML and Related Technologies(141)<br />SCJP2 SCWCD
|
 |
Jayadev Pulaparty
Ranch Hand
Joined: Mar 25, 2002
Posts: 645
|
|
Can you please be a little more elaborate in your explanation, like what the key exactly means here, how is it being used and what the template matching a text() node is doing here. That would be a lot of help for me as i'm key-ignorant Thanks again.
|
 |
Dan Drillich
Ranch Hand
Joined: Jul 09, 2001
Posts: 1121
|
|
I think Vasudha is right. In addition, the code returns the _first_ five unique combinations of attribute and element values. Jayadev, the template matching a text() node is there to suppress output from other text nodes which are not covered by the ItemName rule. I’m still trying to figure it all Cheers, Dan
|
William Butler Yeats: All life is a preparation for something that probably will never happen. Unless you make it happen.
|
 |
Jayadev Pulaparty
Ranch Hand
Joined: Mar 25, 2002
Posts: 645
|
|
<?xml version="1.0"?> <ItemsList> <Items supplier="vinay"> <ItemName code="M1">Mouse</ItemName> <ItemName code="M2">Mouse</ItemName> <ItemName code="K1">KeyBoard</ItemName> </Items> <Items supplier="xyz"> <ItemName code="M1">Mouse</ItemName> <ItemName code="M2">KeyBoard</ItemName> <ItemName code="K2">KeyBoard</ItemName> <ItemName code="K1">KeyBoard</ItemName> </Items> </ItemsList> <xsl:key name="kCodeValue" match="ItemName" use="concat(@code,'::', .)"/> This would give us a set of ItemName nodes with their respective key values as follows (as Vasudha pointed out earlier) - ItemName[0] M1::Mouse ItemName[1] M2::Mouse ItemName[2] K1::KeyBoard ItemName[3] M1::Mouse ItemName[4] M2::KeyBoard ItemName[5] K2::KeyBoard ItemName[6] K1::KeyBoard This node-set will be having "kCodeValue" as its key name and the values shown above as repective key values. Now if we say something like - <xsl:for-each select="key("kCodeValue", "M1::Mouse")>..... Here nodes ItemName[0] and ItemName[3]will be selected by the above xsl statement. I think the entire things lies around this count() function - <xsl:template match="ItemName[count(.| key('kCodeValue',concat(@code,'::', .))[1])=1]"> <xsl:copy-of select="."/> </xsl:template> Not completely clear about what this is doing!!!
|
 |
Jayadev Pulaparty
Ranch Hand
Joined: Mar 25, 2002
Posts: 645
|
|
Dan, I misread the text() node part. I got crazy thinking that all the count() stuff is lying inside the template match for text(). Sorry for that. Coming to the uniqueness of node,key-value pairs, i'm pretty sure that values are being repeated in the node-set as part of the keyname. Just try this little xsl on the source xml and you will come to know this - <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl utput indent="yes" omit-xml-declaration="yes"/> <xsl:key name="kCodeValue" match="ItemName" use="concat(@code,'::', .)"/> <xsl:template match="/"> <xsl:for-each select="key('kCodeValue', 'M1::Mouse')"> <p> <xsl:value-of select="@code"/> <xsl:value-of select="."/> </p> </xsl:for-each> </xsl:template> <xsl:template match="text()"/> </xsl:stylesheet>
|
 |
jim yin
Ranch Hand
Joined: Aug 15, 2002
Posts: 111
|
|
ItemName[0] M1::Mouse ItemName[1] M2::Mouse ItemName[2] K1::KeyBoard ItemName[3] M1::Mouse ItemName[4] M2::KeyBoard ItemName[5] K2::KeyBoard ItemName[6] K1::KeyBoard This node-set will be having "kCodeValue" as its key name and the values shown above as repective key values. Now if we say something like - <xsl:for-each select="key("kCodeValue", "M1::Mouse")>..... Here nodes ItemName[0] and ItemName[3]will be selected by the above xsl statement. I think the entire things lies around this count() function - <xsl:template match="ItemName[count(.| key('kCodeValue',concat(@code,'::', .))[1])=1]"> <xsl:copy-of select="."/> </xsl:template>
My understanding is: key() function will fetch the matched items from the above list first, key(...)[1] will get the first one from the list. "." in count() function will get the current item. "|" is used to eliminate the duplicates if the current node is the same as the first in the list. What I don't understand is: Key() function will produce a list of key-value pairs, while the "." will only get the value since text() will only gives us values. How can they compare with each other?
|
 |
Jayadev Pulaparty
Ranch Hand
Joined: Mar 25, 2002
Posts: 645
|
|
Jim, I guess this is what is happening. First of all duplicates are being allowed as the key values. ItemName[count(.| key('kCodeValue',concat(@code,'::', .))[1])=1]"> By count(. here means the current context of the ItemName node and key('kCodeValue',concat(@code,'::', .)) will return a node-set of 2 nodes for the repeating ones. By saying key('kCodeValue',concat(@code,'::', .))[1], i think we are comparing the current context of ItemName node(.) to be always equal to the first one in the key list. This is enforcing the condition of uniqueness. Not really sure that the | is doing there !!! I need to understand it further
|
 |
Jayadev Pulaparty
Ranch Hand
Joined: Mar 25, 2002
Posts: 645
|
|
Try to replace the relevant stuff with this and you see only the nodes that are repeated 2 times in the output <xsl:template match="ItemName[count(.| key('kCodeValue',concat(@code,'::', .))[1])=2]"> <xsl:copy-of select="."/> </xsl:template> Still not very sure as to how this mechanism is working
|
 |
jim yin
Ranch Hand
Joined: Aug 15, 2002
Posts: 111
|
|
key('kCodeValue',concat(@code,'::', .)) will return a node-set of 2 nodes for the repeating ones. By saying key('kCodeValue',concat(@code,'::', .))[1], i think we are comparing the current context of ItemName node(.) to be always equal to the first one in the key list. This is enforcing the condition of uniqueness.
"|" means union. I think I got it, key() actually produces a list of text values, and "." fetches the current node's text value, how do we compare? They will always be equal, yes.
|
 |
Dan Drillich
Ranch Hand
Joined: Jul 09, 2001
Posts: 1121
|
|
Jim,
"|" means union
Looks more like OR to me :roll:
|
 |
Jayadev Pulaparty
Ranch Hand
Joined: Mar 25, 2002
Posts: 645
|
|
Friends, Just run the following stylesheet on the xml file to get the output. Analysis of the things follows - XSL stylesheet - <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl utput indent="yes" omit-xml-declaration="yes"/> <xsl:key name="kCodeValue" match="ItemName" use="concat(@code,'::', .)"/> <xsl:template match="text()"/> <xsl:template match="ItemName"> <p> <xsl:value-of select="count(.|key('kCodeValue',concat(@code,'::', .))[1])"/> </p> </xsl:template> </xsl:stylesheet> OUTPUT _______ <p>1</p> <p>1</p> <p>1</p> <p>2</p> <p>1</p> <p>1</p> <p>2</p> Analysis of the stuff - _________________________ The key generates the following (node,keyvalue) pairs - ItemName[1] M1::Mouse ItemName[2] M2::Mouse ItemName[3] K1::KeyBoard ItemName[4] M1::Mouse ItemName[5] M2::KeyBoard ItemName[6] K2::KeyBoard ItemName[7] K1::KeyBoard Now the template match ItemName[....] is checking for the ItemName element for the predicate given in the brackets to be true and then only the template will be executed. I guess everything is clear till this point. Now the whole point here is that count(.|key('kCodeValue',concat(@code,'::',.))[1]) will look at the current context node and also checks for the node represented by key('kCodeValue',concat(@code,'::',.))[1] "If they are same,(w.r.t both their context(location)in the tree and the content), only one of them will be taken by the count() function and the count will be 1. If they are different, the count will be 2." This is exactly why we are seeing the count value to be 2 for the succeeding occurences of the ItemName nodes eventhough they have the same content eg., M1::Mouse as their context will not match the Node of occurence[1] in the key nodeset.
|
 |
Jayadev Pulaparty
Ranch Hand
Joined: Mar 25, 2002
Posts: 645
|
|
For further verfication as to how count() works, try the following stylesheet as look at the results. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl utput indent="yes" omit-xml-declaration="yes"/> <xsl:key name="kCodeValue" match="ItemName" use="concat(@code,'::', .)"/> <xsl:template match="text()"/> <xsl:template match="ItemName"> <p> <xsl:value-of select="count(.|//ItemName[@code='M1'])"/> </p> </xsl:template> </xsl:stylesheet>
|
 |
 |
|
|
subject: mock question
|
|
|