Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>Here is a short and simple (no <code>xsl:choose</code>, <code>xsl:when</code> and <code>xsl:otherwise</code>) solution</strong>:</p> <pre><code>&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt; &lt;xsl:output omit-xml-declaration="yes" indent="yes"/&gt; &lt;xsl:strip-space elements="*"/&gt; &lt;xsl:template match="node()|@*"&gt; &lt;xsl:param name="pParent" select="/.."/&gt; &lt;xsl:copy&gt; &lt;xsl:apply-templates select="node()|@*"&gt; &lt;xsl:with-param name="pParent" select="$pParent"/&gt; &lt;/xsl:apply-templates&gt; &lt;/xsl:copy&gt; &lt;/xsl:template&gt; &lt;xsl:template match="prot"&gt; &lt;xsl:copy&gt; &lt;xsl:copy-of select="@*"/&gt; &lt;xsl:apply-templates select="../prot/node"&gt; &lt;xsl:with-param name="pParent" select="."/&gt; &lt;/xsl:apply-templates&gt; &lt;/xsl:copy&gt; &lt;/xsl:template&gt; &lt;xsl:template match="node/text()"&gt; &lt;xsl:param name="pParent" select="/.."/&gt; &lt;xsl:variable name="vSameParent" select= "boolean(not((../.. | $pParent)[2]))"/&gt; &lt;xsl:value-of select= "concat(substring('-', 1 +$vSameParent), self::node()[$vSameParent] ) "/&gt; &lt;/xsl:template&gt; &lt;/xsl:stylesheet&gt; </code></pre> <p><strong>when this transformation is applied on the provided XML document</strong>:</p> <pre><code>&lt;data&gt; &lt;prot seq="AAA"&gt; &lt;node num="4"&gt;1345&lt;/node&gt; &lt;/prot&gt; &lt;prot seq="BBB"&gt; &lt;node num="7"&gt;6666&lt;/node&gt; &lt;/prot&gt; &lt;prot seq="CCC"&gt; &lt;node num="10"&gt;3e33&lt;/node&gt; &lt;/prot&gt; &lt;/data&gt; </code></pre> <p><strong>the wanted, correct result is produced</strong>:</p> <pre><code>&lt;data&gt; &lt;prot seq="AAA"&gt; &lt;node num="4"&gt;1345&lt;/node&gt; &lt;node num="7"&gt;-&lt;/node&gt; &lt;node num="10"&gt;-&lt;/node&gt; &lt;/prot&gt; &lt;prot seq="BBB"&gt; &lt;node num="4"&gt;-&lt;/node&gt; &lt;node num="7"&gt;6666&lt;/node&gt; &lt;node num="10"&gt;-&lt;/node&gt; &lt;/prot&gt; &lt;prot seq="CCC"&gt; &lt;node num="4"&gt;-&lt;/node&gt; &lt;node num="7"&gt;-&lt;/node&gt; &lt;node num="10"&gt;3e33&lt;/node&gt; &lt;/prot&gt; &lt;/data&gt; </code></pre> <p><strong>Explanation</strong>:</p> <ol> <li><p>We use and override a modified version of the identity rule -- one which accepts and passes a parameter named <code>$pParent</code>.</p></li> <li><p>The parameter <code>$pParent</code> contains the <code>node</code> element that issued <code>xsl:apply-templates</code>, part of which is the processing of the current node.</p></li> <li><p>We have two templates that override the identity rule. The first overriding template matches any <code>prot</code> element. It is almost identical to the identity rule, but it sets the <code>$pParent</code> parameter with a meaningful value (this node itself).</p></li> <li><p>The second overriding template matches any text node that is a child of any <code>node</code> element. Here, depending on whether or not the value of <code>$pParent</code> identifies the grandparent of the matched text node, we output respectively, the value of the text node or just <code>"-"</code>.</p></li> <li><p>The decision what to output is done without using any explicit conditional instruction. Instead, we use the XPath <code>concat()</code> function with two arguments, exactly one of which is a non-empty string. To assure this property, we use the boolean variable <code>$vSameParent</code>, which is specified in such a way that its value is <code>true()</code> exactly when the grand-parent of the matched text node is identical to the node contained in <code>$pParent</code>. Finally, we use the fact that when used as a number, a boolean value of <code>true()</code> is converted to <code>1</code> and a boolean value of <code>false()</code> is converted to <code>0</code>.</p></li> </ol> <p><strong>Update</strong>: This is a new solution -- to the modified by the OP problem:</p> <pre><code>&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt; &lt;xsl:output omit-xml-declaration="yes" indent="yes"/&gt; &lt;xsl:strip-space elements="*"/&gt; &lt;xsl:key name="kNodeByNum" match="node" use="@num"/&gt; &lt;xsl:template match="node()|@*"&gt; &lt;xsl:param name="pNum"/&gt; &lt;xsl:copy&gt; &lt;xsl:apply-templates select="node()|@*"&gt; &lt;xsl:with-param name="pNum" select="$pNum"/&gt; &lt;/xsl:apply-templates&gt; &lt;/xsl:copy&gt; &lt;/xsl:template&gt; &lt;xsl:template match="prot"&gt; &lt;xsl:copy&gt; &lt;xsl:copy-of select="@*"/&gt; &lt;xsl:apply-templates select= "../prot/node [generate-id() = generate-id(key('kNodeByNum', @num)[1]) ] "&gt; &lt;xsl:with-param name="pNum" select="node/@num"/&gt; &lt;/xsl:apply-templates&gt; &lt;/xsl:copy&gt; &lt;/xsl:template&gt; &lt;xsl:template match="node/text()"&gt; &lt;xsl:param name="pNum" select="/.."/&gt; &lt;xsl:variable name="vSameNum" select= "../@num = $pNum"/&gt; &lt;xsl:value-of select= "concat(substring('-', 1 +$vSameNum), self::node()[$vSameNum] ) "/&gt; &lt;/xsl:template&gt; &lt;/xsl:stylesheet&gt; </code></pre> <p><strong>when this transformation is applied to the provided XML document</strong>:</p> <pre><code>&lt;data&gt; &lt;prot seq="AAA"&gt; &lt;node num="4"&gt;1345&lt;/node&gt; &lt;/prot&gt; &lt;prot seq="BBB"&gt; &lt;node num="7"&gt;6666&lt;/node&gt; &lt;/prot&gt; &lt;prot seq="CCC"&gt; &lt;node num="10"&gt;3e33&lt;/node&gt; &lt;/prot&gt; &lt;prot seq="DDD"&gt; &lt;node num="4"&gt;1345&lt;/node&gt; &lt;/prot&gt; &lt;prot seq="EEE"&gt; &lt;node num="10"&gt;3e33&lt;/node&gt; &lt;/prot&gt; &lt;/data&gt; </code></pre> <p><strong>the new wanted result is produced</strong>:</p> <pre><code>&lt;data&gt; &lt;prot seq="AAA"&gt; &lt;node num="4"&gt;1345&lt;/node&gt; &lt;node num="7"&gt;-&lt;/node&gt; &lt;node num="10"&gt;-&lt;/node&gt; &lt;/prot&gt; &lt;prot seq="BBB"&gt; &lt;node num="4"&gt;-&lt;/node&gt; &lt;node num="7"&gt;6666&lt;/node&gt; &lt;node num="10"&gt;-&lt;/node&gt; &lt;/prot&gt; &lt;prot seq="CCC"&gt; &lt;node num="4"&gt;-&lt;/node&gt; &lt;node num="7"&gt;-&lt;/node&gt; &lt;node num="10"&gt;3e33&lt;/node&gt; &lt;/prot&gt; &lt;prot seq="DDD"&gt; &lt;node num="4"&gt;1345&lt;/node&gt; &lt;node num="7"&gt;-&lt;/node&gt; &lt;node num="10"&gt;-&lt;/node&gt; &lt;/prot&gt; &lt;prot seq="EEE"&gt; &lt;node num="4"&gt;-&lt;/node&gt; &lt;node num="7"&gt;-&lt;/node&gt; &lt;node num="10"&gt;3e33&lt;/node&gt; &lt;/prot&gt; &lt;/data&gt; </code></pre> <p><strong>Explanation</strong>: The same main ideas as with the original problem, with added <strong><a href="http://www.jenitennison.com/xslt/grouping/muenchian.html" rel="nofollow">Muenchian Grouping</a></strong>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload