Connecting Tech Pros Worldwide Help | Site Map

xsl Nodename occurs more than once on the same level

Newbie
 
Join Date: Mar 2009
Posts: 4
#1: Mar 26 '09
hello,
I am new to Bytes and I am not sure if this is the right plattform. but I found several posts regarding XSL. (If this is not the rigth forum, I apologize. Could you point me to another one then please.)

I have an xsl stylesheet which reads an xml input file and produces an xml output which shows the structure of the source xml file.

I want to include the following information in the output:
which of the output-nodes has any siblings with the same name:

But I have difficulties modifying the stylesheet to achieve this.


example of the source xml:
Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <book>
  3. <chapter>
  4. <title/>
  5. <lines></lines>
  6. <lines></lines>
  7. </chapter>
  8. <chapter>
  9. <title/>
  10. <lines></lines>
  11. </chapter>
  12. </book>
  13.  
the output:
Expand|Select|Wrap|Line Numbers
  1. <book>
  2. <chapter>
  3. <title/>
  4. <lines/>
  5. </chapter>
  6. </book>
the stylesheet - which I copied from the net:

Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  3. <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
  4. <xsl:template match="/" name="subtree">
  5.   <xsl:param name="parents" select="."/>
  6.   <xsl:for-each-group select="$parents/*" group-by="name()">
  7.   <xsl:copy>
  8.   <xsl:call-template name="subtree">
  9.   <xsl:with-param name="parents" select="current-group()"/>
  10.   </xsl:call-template>
  11.   </xsl:copy>
  12.   </xsl:for-each-group>
  13. </xsl:template>
  14. </xsl:stylesheet>
thanks in advance for any hints
Markus
Moderator
 
Join Date: Mar 2006
Posts: 1,103
#2: Mar 27 '09

re: xsl Nodename occurs more than once on the same level


Sorry, do you mean which of the elements repeat?

<xsl:if test="count(current-group() &gt; 1)">
Multiple elements of this type.

Or do you mean which of the elements repeat within the same element? Probably something like
<xsl:if test="current-group[local-name() = local-name(following-sibling::*)]">
Newbie
 
Join Date: Mar 2009
Posts: 4
#3: Apr 2 '09

re: xsl Nodename occurs more than once on the same level


thanks very much for your answer.

I apologize that I am slow to answer.

To answer your question:
I want to know if elements share the same parent element.


So I tried your idea with looking for a following-sbiling with identical name.
But I cannot get it figured out. If I write:
following-sibling::*[name()=name(.)]

I get all siblings of the current node not only the ones with identical name.
I obviously misunderstand the syntax of xpath but cannot see where.

I also do not understand part of your solution:
local-name(following-sibling::*)
is this valid xpath? how can I ask for the local name of all following-siblings??


thanks Markus
Dormilich's Avatar
Moderator
 
Join Date: Aug 2008
Location: Leipzig, Germany
Posts: 3,629
#4: Apr 2 '09

re: xsl Nodename occurs more than once on the same level


Quote:

Originally Posted by Ohlenroth View Post

I also do not understand part of your solution:
local-name(following-sibling::*)
is this valid xpath? how can I ask for the local name of all following-siblings??

yes, it's valid XPath and it gives you the local name (i.e. tag name without namespace prefix) of the next sibling, regardless of the sibling's tag name.

you can't easily get the local name of all siblings (I guess it involves sorting), because they may be different and local-name() accepts only a single node.
Newbie
 
Join Date: Mar 2009
Posts: 4
#5: Apr 2 '09

re: xsl Nodename occurs more than once on the same level


thanks for your help.

I was puzzeld about the xpath expression because in the program I use it is a legal xpath expression if the debugger is in the top template. But on the next template the debugger says: "Error in xpath expression...." I seem to fail to understand important things in xpath.


In order to find a solution to my question, I tried out to find an xpath expression which finds out if the current node has any siblings:

I have the following input:

Expand|Select|Wrap|Line Numbers
  1. <artikel>
  2. <Lemma>Lemma</Lemma>
  3. <Variante code="1">V1</Variante>
  4. <Variante code="2">V2</Variante>
  5. <Variante code="3">V3</Variante>
  6. <Grammatik>gramma</Grammatik>
  7. </artikel>
I ask - once the current node is <Variante/> -:
count(parent::*/*[name()='Variante'])
this gives me as I had hoped "3" as answer.

But if I write instead
count(parent::*/*[name()=local-name()])
I get 5 as answer:
although xpath: local-name() gives me 'Variante' as name:

Why should I get a different answer? I seem to fail to understand important parts in XPATH.
Dormilich's Avatar
Moderator
 
Join Date: Aug 2008
Location: Leipzig, Germany
Posts: 3,629
#6: Apr 2 '09

re: xsl Nodename occurs more than once on the same level


Quote:

Originally Posted by Ohlenroth View Post

But if I write instead
count(parent::*/*[name()=local-name()])
I get 5 as answer:
although xpath: local-name() gives me 'Variante' as name:

Why should I get a different answer? I seem to fail to understand important parts in XPATH.

it gives you 5 because the parent element has 5 children and you test, whether the tag name contains a namespace prefix because name() and local-name() are pointing to the same node (Lemma, Grammatik, 3x Variante).

try count(parent::*/*[local-name(current())=local-name()]). if that's not giving 3 I can only think of using a variable.
Newbie
 
Join Date: Mar 2009
Posts: 4
#7: Apr 2 '09

re: xsl Nodename occurs more than once on the same level


Yes, your expression gives the correct answer.
I shall fit it in my program
thanks for your help and time.
Markus
Reply