Delete / Remove node from XPathNodeIterator, given an XPath
Posted
by RymdPung
on Stack Overflow
See other posts from Stack Overflow
or by RymdPung
Published on 2010-03-26T16:38:19Z
Indexed on
2010/06/02
4:23 UTC
Read the original article
Hit count: 357
First of all, if someone has a different, perhaps shorter (or better), solution to the problem, it's welcome as well.
I'm trying to "simply" remove (almost) duplicate elements in XSLT. There's some (metadata) nodes i don't want to include when comparing, and i couldn't figure out how do do that in XSLT so thought i'd extend it with a function removing these nodes. Like so:
<xsl:for-each select="abx:removeNodes(d/df600|d/df610|d/df611|d/df630|d/df650|d/df651|d/df655, '*[@key="i1" or @key="i2" or key="db"]')">
<xsl:if test="not(node()=preceding-sibling::*)">
blah
</xsl:if>
</xsl:for-each>
And the extension, which doesn't work so well... (C#)
public XPathNodeIterator removeNodes(XPathNodeIterator p_NodeIterator, String removeXPath)
{
Logger Logger = new Logger("xslt");
Logger.Log("removeNodes(removeXPath={0}):", removeXPath);
foreach (XPathNavigator CurrentNode in p_NodeIterator)
{
Logger.Log("removeNodes(): CurrentNode.OuterXml={0}.", CurrentNode.OuterXml);
foreach (XPathNavigator CurrentSubNode in CurrentNode.Select(removeXPath))
{
Logger.Log("removeNodes(): CurrentSubNode.OuterXml={0}.", CurrentSubNode.OuterXml);
// How do i delete this node!?
//CurrentSubNode.DeleteSelf();
}
}
return p_NodeIterator;
}
My initial approach using 'CurrentSubNode.DeleteSelf();' doesn't work because it gets confused and loses its position in the XPathNavigator, causing it to only delete the first item it finds using "removeXPath". Something like a DeleteAndMoveNext() would be nice but there seems to be no such method...
Example data:
<df650>
<df650 key="i1"> </df650>
<df650 key="i2">0</df650>
<df650 key="a">foo</df650>
<df650 key="x">bar</df650>
<df650 key="db">someDB</df650>
<df650 key="id">b2</df650>
<df650 key="dsname">someDS</df650>
</df650>
..and then another identical node (if you ignore the meta fields; db,id,dsname).
<df650>
<df650 key="i1"> </df650>
<df650 key="i2">0</df650>
<df650 key="a">foo</df650>
<df650 key="x">bar</df650>
<df650 key="db">someOtherDB</df650>
<df650 key="id">b2</df650>
<df650 key="dsname">someOtherDS</df650>
</df650>
The result should be...
<df650>
<df650 key="i1"> </df650>
<df650 key="i2">0</df650>
<df650 key="a">foo</df650>
<df650 key="x">bar</df650>
</df650>
© Stack Overflow or respective owner