Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7081151
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T06:53:03+00:00 2026-05-28T06:53:03+00:00

This one I really think is not possible to solve through XSLT, so that

  • 0

This one I really think is not possible to solve through XSLT, so that I will have to do something with JS or just do not implement.
But before giving up, of course I have to post here to see if I am wrong and XSLT can do this kind of logic.

EDIT: now I’m starting to see that it is possible, getting closer

EDIT2: I have to correct a mistake in the XML code provided. The solution should be able to handle multiple nodes with the same values.

The concept is that I need to re-format the code including empty tags that reflect the total number of different values. Difficult to explain, much easier to understand looking at the code.

Initial XML code

<data>
    <prot seq="AAA">
        <node num="4">1345</node>
    </prot>
    <prot seq="BBB">
        <node num="7">6666</node>
    </prot>
    <prot seq="CCC">
        <node num="10">3e33</node>
    </prot>
    <prot seq="DDD">
        <node num="4">1345</node>
    </prot>
    <prot seq="EEE">
        <node num="10">3e33</node>
    </prot>
</data>

And the wished output

<root>
    <prot seq="AAA">
        <node num="4">1345</node><node num="7">-</node><node num="10">-</node>
    </prot>
    <prot seq="BBB">
        <node num="4">-</node><node num="7">6666</node><node num="10">-</node>
    </prot>
    <prot seq="CCC">
        <node num="4">-</node><node num="7">-</node><node num="10">3e33</node>
    </prot>
    <prot seq="DDD">
        <node num="4">1345</node><node num="7">-</node><node num="10">-</node>
    </prot>
    <prot seq="EEE">
        <node num="4">-</node><node num="7">-</node><node num="10">3e33</node>
    </prot>
</root>

Any idea?

Thanks!

EDIT3: from Dimitri solution, I’ve ended up with this simplified solution

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kNodeByNum" match="/data/prot/node" use="@num"/>
<xsl:template match="/">
    <root>
        <xsl:apply-templates select="/data/prot"/>
    </root>
</xsl:template>
<xsl:template match="/data/prot">
  <xsl:variable name="current_num" select="node/@num"/>
  <xsl:variable name="current_value" select="node"/>
  <prot seq="{@seq}">
    <xsl:for-each select="/data/prot/node[
    generate-id()
    =
    generate-id(key('kNodeByNum', @num)[1])
    ]">
      <xsl:choose>
        <xsl:when test="@num = $current_num">
          <node num="{@num}"><xsl:value-of select="$current_value"/></node>
        </xsl:when>
        <xsl:otherwise>
          <node num="{@num}">-</node>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </prot>
</xsl:template>
</xsl:stylesheet>

However, this code also cannot handle the number of nodes in firefox and goes in a forever-like loop (and I have to force firefox to close).

But I am thinking that this has nothing to do with the number of nodes but that there is something wrong with the code (?)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T06:53:04+00:00Added an answer on May 28, 2026 at 6:53 am

    Here is a short and simple (no xsl:choose, xsl:when and xsl:otherwise) solution:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:template match="node()|@*">
      <xsl:param name="pParent" select="/.."/>
      <xsl:copy>
       <xsl:apply-templates select="node()|@*">
        <xsl:with-param name="pParent" select="$pParent"/>
       </xsl:apply-templates>
      </xsl:copy>
     </xsl:template>
    
     <xsl:template match="prot">
      <xsl:copy>
       <xsl:copy-of select="@*"/>
       <xsl:apply-templates select="../prot/node">
        <xsl:with-param name="pParent" select="."/>
       </xsl:apply-templates>
      </xsl:copy>
     </xsl:template>
    
     <xsl:template match="node/text()">
      <xsl:param name="pParent" select="/.."/>
    
      <xsl:variable name="vSameParent" select=
      "boolean(not((../.. | $pParent)[2]))"/>
    
      <xsl:value-of select=
      "concat(substring('-', 1 +$vSameParent),
                        self::node()[$vSameParent]
                       )
      "/>
     </xsl:template>
    </xsl:stylesheet>
    

    when this transformation is applied on the provided XML document:

    <data>
        <prot seq="AAA">
            <node num="4">1345</node>
        </prot>
        <prot seq="BBB">
            <node num="7">6666</node>
        </prot>
        <prot seq="CCC">
            <node num="10">3e33</node>
        </prot>
    </data>
    

    the wanted, correct result is produced:

    <data>
       <prot seq="AAA">
          <node num="4">1345</node>
          <node num="7">-</node>
          <node num="10">-</node>
       </prot>
       <prot seq="BBB">
          <node num="4">-</node>
          <node num="7">6666</node>
          <node num="10">-</node>
       </prot>
       <prot seq="CCC">
          <node num="4">-</node>
          <node num="7">-</node>
          <node num="10">3e33</node>
       </prot>
    </data>
    

    Explanation:

    1. We use and override a modified version of the identity rule — one which accepts and passes a parameter named $pParent.

    2. The parameter $pParent contains the node element that issued xsl:apply-templates, part of which is the processing of the current node.

    3. We have two templates that override the identity rule. The first overriding template matches any prot element. It is almost identical to the identity rule, but it sets the $pParent parameter with a meaningful value (this node itself).

    4. The second overriding template matches any text node that is a child of any node element. Here, depending on whether or not the value of $pParent identifies the grandparent of the matched text node, we output respectively, the value of the text node or just "-".

    5. The decision what to output is done without using any explicit conditional instruction. Instead, we use the XPath concat() function with two arguments, exactly one of which is a non-empty string. To assure this property, we use the boolean variable $vSameParent, which is specified in such a way that its value is true() exactly when the grand-parent of the matched text node is identical to the node contained in $pParent. Finally, we use the fact that when used as a number, a boolean value of true() is converted to 1 and a boolean value of false() is converted to 0.

    Update: This is a new solution — to the modified by the OP problem:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:key name="kNodeByNum" match="node" use="@num"/>
    
     <xsl:template match="node()|@*">
      <xsl:param name="pNum"/>
      <xsl:copy>
       <xsl:apply-templates select="node()|@*">
        <xsl:with-param name="pNum" select="$pNum"/>
       </xsl:apply-templates>
      </xsl:copy>
     </xsl:template>
    
     <xsl:template match="prot">
      <xsl:copy>
       <xsl:copy-of select="@*"/>
       <xsl:apply-templates select=
       "../prot/node
                [generate-id()
                =
                 generate-id(key('kNodeByNum', @num)[1])
                ]
       ">
        <xsl:with-param name="pNum" select="node/@num"/>
       </xsl:apply-templates>
      </xsl:copy>
     </xsl:template>
    
     <xsl:template match="node/text()">
      <xsl:param name="pNum" select="/.."/>
    
      <xsl:variable name="vSameNum" select=
      "../@num = $pNum"/>
    
      <xsl:value-of select=
      "concat(substring('-', 1 +$vSameNum),
                        self::node()[$vSameNum]
                       )
      "/>
     </xsl:template>
    </xsl:stylesheet>
    

    when this transformation is applied to the provided XML document:

    <data>
        <prot seq="AAA">
            <node num="4">1345</node>
        </prot>
        <prot seq="BBB">
            <node num="7">6666</node>
        </prot>
        <prot seq="CCC">
            <node num="10">3e33</node>
        </prot>
        <prot seq="DDD">
            <node num="4">1345</node>
        </prot>
        <prot seq="EEE">
            <node num="10">3e33</node>
        </prot>
    </data>
    

    the new wanted result is produced:

    <data>
       <prot seq="AAA">
          <node num="4">1345</node>
          <node num="7">-</node>
          <node num="10">-</node>
       </prot>
       <prot seq="BBB">
          <node num="4">-</node>
          <node num="7">6666</node>
          <node num="10">-</node>
       </prot>
       <prot seq="CCC">
          <node num="4">-</node>
          <node num="7">-</node>
          <node num="10">3e33</node>
       </prot>
       <prot seq="DDD">
          <node num="4">1345</node>
          <node num="7">-</node>
          <node num="10">-</node>
       </prot>
       <prot seq="EEE">
          <node num="4">-</node>
          <node num="7">-</node>
          <node num="10">3e33</node>
       </prot>
    </data>
    

    Explanation: The same main ideas as with the original problem, with added Muenchian Grouping.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I think this is not really possible but worth asking anyway. Say I have
this one is really easy. I'm trying to create a Regular Expression that will
Really ripping my hair out on this one. I have a JAAS Authentication Provider
I'm not really sure how to google this one . I would like to
I can't seem to figure this one out. I have a validator-type script that
Boy, this one is really weird. I expect the following code to print 1990,
Ok, this one is really weird... I can't show code for it exactly cause
Probably a really simple one this - I'm starting out with C# and need
I'm really frustrated with this one. A few weeks ago I got it working
I'm really stumped by this one! The StackFrame object ( MSDN Link ) has

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.