473,386 Members | 1,710 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Finding/removing nodes with attribute value

Hi. I have a rather large xml document (object) that can have one or
more nodes with a certain attribute throughout (at ANY depth, not at
the same level necessarily). I need to find this attribute and remove
the containing node (and child nodes) if it has a certain value.

I'm able to find the attributes using an XmlTextReader. Once found,
can someone help me get the XPath at that point? I would then use
this to remove the node from the document object.

Or can someone suggest another appoach to navigate the xml and find
and remove the nodes? Thanks.
Nov 12 '05 #1
2 10646
"Greg" <gr********@earthlink.net> wrote in message news:c5**************************@posting.google.c om...
Hi. I have a rather large xml document (object) that can have one or
more nodes with a certain attribute throughout (at ANY depth, not at
the same level necessarily). I need to find this attribute and remove
the containing node (and child nodes) if it has a certain value.


Since you can find these attributes in your XmlTextReader, why bother
with loading it into a XmlDocument and then using XPath to remove
the nodes when you can filter them out all within your XmlTextReader?

Here's an example XmlTextReader named NodeStripReader that takes
out all elements marked with an attribute named exclude (whatever it's
value, although it should be trivial to fine-tune the filter to apply whatever
attribute value criteria your application requires), including all child nodes
of these elements.

- - - NodeStripReader.cs
using System;
using System.IO;
using System.Text;
using System.Xml;

namespace NS1
{
/// <summary>
/// Specialized <see cref="System.Xml.XmlTextReader"/> that strips out nodes
/// marked with an <u>exclude</u> attribute, and child nodes of an excluded
/// element in a streaming manner.
/// </summary>
public class NodeStripReader : XmlTextReader
{
private string excludeAttrName;

/// <summary>
/// Creates a <see cref="NodeStripReader"/> that excludes all nodes beneath
/// an element having an attribute named <u>exclude</u>.
/// </summary>
/// <param name="source">
/// The <see cref="System.IO.TextReader">TextReader</see> serving as the
/// source for the streaming XML.
/// </param>
public NodeStripReader(TextReader source) : base(source)
{
excludeAttrName = NameTable.Add("exclude");
}

/// <summary>
/// Excludes all nodes read from under the <see cref="NodeStripReader"/>'s
/// starting position.
/// </summary>
/// <returns>
/// True when there are nodes remaining in the document to read.
/// </returns>
protected bool ConsumeExcludedNodes( )
{
// moreToRead is necessary in case I exclude the document element,
// and Read( ) needs to bubble up that the end-of-document has been
// reached.
//
bool moreToRead;

// As long as I haven't ascended to at least the next sibling
// of the node I started excluding at, I keep consuming nodes.
// moreToConsume lets me check this for equality after a first
// pass through the loop, since I must consume at least one
// node.
//
int startingDepth = base.Depth;
bool moreToConsume = true;

// As long sa there are nodes, and I'm not finished consuming them.
//
while ((true == (moreToRead = base.Read( ))) && moreToConsume)
{
XmlNodeType nodeType = base.NodeType;

// If the consumed node I've read is an Element, then I've gone
// one level deeper.
//
if (nodeType == XmlNodeType.EndElement)
{
// If the consumed node I've read is an EndElement, then
// I'm about to ascend one level, check whether I've
// excluded all of the nodes I meant to exclude.
//
moreToConsume = (startingDepth != base.Depth);
}
// XmlNodeTypes of Text, Entity, Comment, everything beneath
// the Element I started to exclude are all quietly eaten.
}

return moreToRead;
}

/// <summary>
/// Reads nodes from the source, excludes any nodes and their descendants
/// that contain an attribute node named <u>exclude</u>.
/// </summary>
/// <returns>
/// True when nodes remain in the document to be read.
/// </returns>
/// <remarks>
/// <seealso cref="System.Xml.XmlTextReader.Read"/>
/// </remarks>
public override bool Read( )
{
// Must call base Read( ) to do anything, including initial transition
// from ReadState.Initial -> ReadState.Interactive.
//
bool moreToRead = base.Read( );

// Nothing to do if this read was the End-of-Document.
//
if (moreToRead)
{
if (base.NodeType == XmlNodeType.Element)
{
// If this node is the start of an element, then I need to check
// for the presence of an exclude attribute.
//
string excludeValue = base.GetAttribute(excludeAttrName, "");
if (null != excludeValue)
{
// Consume all descendant-or-self elements at this point;
// the reader is at the next non-excluded element (sibling
// or parent of this element) or the end-of-document when
// this call returns.
//
moreToRead = this.ConsumeExcludedNodes( );
}
}
}

return moreToRead;
}
}
}
- - -

All pretty simple, and more efficient than building XPath expressions (I mean,
you could use a Stack as your XmlTextReader subclass descends to save off
the element names until you get to an excluded element, and then as soon as
you do you'd store that Stack and use it later to build the location steps of an
XPath expression from the bottom-up).

Here's a test app to demonstrate how NodeStripReader can be applied to a
situation such as yours.

- - - TestApp.cs
using System;
using System.IO;
using System.Text;
using System.Xml;

namespace NS1
{
class NodeStripReaderApp
{
static void Main( string[] args)
{
string xml = "<root><firstChild exclude=\"true\"><grandChild/>" +
"<text>Text</text></firstChild><secondChild>Text</secondChild></root>";
StringReader reader = new StringReader( xml);
NodeStripReader textReader = new NodeStripReader( reader);
XmlDocument doc = new XmlDocument( );
doc.Load( textReader);
Console.WriteLine( doc.OuterXml);

Console.ReadLine( );
}
}
}
- - -

This produces the following output,

<root><secondChild>Text</secondChild></root>

and you'll observe that the excluded element and it's child nodes, the following tree,

<firstChild exclude='true'><grandChild/><text>Text</text></firstChild>

have all been filtered out from the resulting XML.
Derek Harmon
Nov 12 '05 #2


Greg wrote:
I have a rather large xml document (object) that can have one or
more nodes with a certain attribute throughout (at ANY depth, not at
the same level necessarily). I need to find this attribute and remove
the containing node (and child nodes) if it has a certain value.

I'm able to find the attributes using an XmlTextReader. Once found,
can someone help me get the XPath at that point? I would then use
this to remove the node from the document object.

Or can someone suggest another appoach to navigate the xml and find
and remove the nodes?


Well XPath allows you to find nodes at any level e.g.
//element-name[@attribute-name = 'attribute value']
gives you all the elements at any level with the attribute value as
specified so I am not sure you need an XmlTextReader if you later on
want to use an XmlDocument anyway to remove nodes.

--

Martin Honnen
http://JavaScript.FAQTs.com/
Nov 12 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Johannes Lebek | last post by:
Hi there, somehow, I cannot access nodes that are stored in a variable. I'm using Xalan 2.5.1 and the following commands: ================ BEGIN ==================== <xsl:variable...
3
by: Jorn W Janneck | last post by:
hello everyone. i have the sort of question that makes me feel like i am missing the forest for the trees, so apologies if i am missing the blatantly obvious here. i am using saxon, and mostly...
6
by: Matt | last post by:
Hello, I have an XML document similar to the following: <DataItems> <Data xmlns="http://www.me.com"> <DataInformation xmlns:a="http://www.me.com/ASettings" xsi:type="a:Stuff1">...
10
by: Johnny Ooi | last post by:
I've written a template that does some work on a subtree, but I want to replace the subtree that I originally worked on. How would I do this? Confused, Okay, here's an example: <node> <node>...
4
by: Porthos | last post by:
Hi All, I'm trying to find the minimum value of a set of data (see below). I want to compare the lengths of these attribute values and display the lowest one. This would be simple if I could...
2
by: bmgz | last post by:
I have written a simple function that validates a form based on the form objects' className attribute. The form basically write a "field required" message next to the form element that is blank(and...
7
by: Simon Hart | last post by:
Hi, I have a requirement to remove the xmlns from the DOM in order to pass over to MS CRM 3.0 Fetch method.It seems the fetch method blows up if there is a xmlns present!?! The reason I have a...
1
by: Christian Rühl | last post by:
hey! what i wanna do sounds very simple at first, but it turned out to be a real bone crusher... i want to check if a treeView node is checked and if a correspondent node in my xml config file...
1
by: lejason | last post by:
Hi, I have an XML file that is a list of product models and info. The list will eventually contain about 100 products, each product having multiple elements for things like names,...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.