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

Filed under:
|
|

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=&quot;i1&quot; or @key=&quot;i2&quot; or key=&quot;db&quot;]')">
   <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

Related posts about c#

Related posts about Xml