469,284 Members | 2,492 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,284 developers. It's quick & easy.

xsl Nodename occurs more than once on the same level

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
Mar 26 '09 #1
6 3628
jkmyoung
2,057 Expert 2GB
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::*)]">
Mar 27 '09 #2
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
Apr 2 '09 #3
Dormilich
8,651 Expert Mod 8TB
@Ohlenroth
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.
Apr 2 '09 #4
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.
Apr 2 '09 #5
Dormilich
8,651 Expert Mod 8TB
@Ohlenroth
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.
Apr 2 '09 #6
Yes, your expression gives the correct answer.
I shall fit it in my program
thanks for your help and time.
Markus
Apr 2 '09 #7

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

73 posts views Thread by RobertMaas | last post: by
220 posts views Thread by Brandon J. Van Every | last post: by
4 posts views Thread by John Bailo | last post: by
54 posts views Thread by zhaoyandong | last post: by
116 posts views Thread by Mike MacSween | last post: by
109 posts views Thread by sonugeetha | last post: by
8 posts views Thread by Brian Tkatch | last post: by
3 posts views Thread by Eric Layman | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.