Jo,
You could extend your XPath to restrict the comparison to the same nodeA
ancestor like this -- instead of
deep-equal(.,preceding::*[name()=current()/name()][@id=current()/@id][1])
say
deep-equal(.,ancestor::nodeA//*[ ... ][ ... ][. << current()][1]
(Untested.)
But the logic is complex enough here that I would be tempted to refactor
into a function. Something like
<xsl:function name="d:duplicate" as="xs:boolean">
<xsl:param name="i" as="element()">
<!-- Given a node, return true() iff another node exists
inside a nodeA ancestor with the same name and @id,
but before this one, with the same value -->
<xsl:sequence select="exists(
$i/ancestor::nodeA//*
[name()=name($i)]
[@id=$i/@id]
[. << $i]
[deep-equal(.,$i)])"/>
</xsl:function>
Then
<xsl:match="*[d:duplicate(.)]"/>
Note: untested.
This also exposes what might be a bug in your logic. If you toss only
nodes that have the same content as the first node with the same name
and @id, you will allow duplicates that appear after the first. (That
is, as long as the second and third are not the same as the first, they
will both be kept, even if the third is the same as the second.)
If you mean to keep such duplicates, the function would have to be adjusted.
Cheers,
Wendell
On 6/8/2012 2:43 AM, Jo Na wrote:
Hi,
I have this input:
<myroot>
<nodeA id="a">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"> <!-- second consecutive
create, we remove this -->
<somechild>a</somechild>
</item1>
<item1 id="0" method="create"> <!-- third consecutive
create, BUT children have different value , so we don't remove this
-->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
<item1 id="0" method="change"> <!-- second consecutive
create, we remove this -->
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
</myroot>
and this is my xslt 2.0:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template
match="*[*][deep-equal(.,preceding::*[name()=current()/name()][@id=current()/@id][1])]"/>
</xsl:stylesheet>
How to make that works for multiple nodeA with different id? Right now
my XSLT only works for 1 nodeA.
The objective is to remove successive duplicate with the same element
name item1 item2 etc, same id and same method.
This is what the multiple nodeA input and the expected output:
<myroot>
<nodeA id="a">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"> <!-- third consecutive
create, BUT children have different value , so we don't remove this
-->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
<nodeA id="b">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"> <!-- third consecutive
create, BUT children have different value , so we don't remove this
-->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
</myroot>
Expected Output:
<myroot>
<nodeA id="a">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"> <!-- third consecutive
create, BUT children have different value , so we don't remove this
-->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
<nodeA id="b">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"> <!-- third consecutive
create, BUT children have different value , so we don't remove this
-->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
</myroot>
Thanks very much.
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail:<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--
======================================================================
Wendell Piez
mailto:wapiez(_at_)mulberrytech(_dot_)com
Mulberry Technologies, Inc. http://www.mulberrytech.com
17 West Jefferson Street Direct Phone: 301/315-9635
Suite 207 Phone: 301/315-9631
Rockville, MD 20850 Fax: 301/315-8285
----------------------------------------------------------------------
Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--