File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

mock question

 
jim yin
Ranch Hand
Posts: 111
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

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
Posts: 111
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is a tough one, could Jayadev and Dan comment on this? Thanks.
 
Jayadev Pulaparty
Ranch Hand
Posts: 662
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 111
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 86
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Jayadev Pulaparty
Ranch Hand
Posts: 662
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 1183
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
 
Jayadev Pulaparty
Ranch Hand
Posts: 662
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
<?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
Posts: 662
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 111
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

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
Posts: 662
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 662
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 111
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

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
Posts: 1183
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jim,
"|" means union

Looks more like OR to me :roll:
 
Jayadev Pulaparty
Ranch Hand
Posts: 662
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 662
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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>
 
I agree. Here's the link: http://aspose.com/file-tools
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic