473,399 Members | 2,146 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,399 software developers and data experts.

What is the fastest/efficient way to replace the root element?

Suppose I have an xml fragment like:

<mother>
<child name="Bob" sex="M"/>
<child name="Jane" sex="F"/>
...
</mother>

If I wanted to replace the <mother> element to <father> element, what is the
fastest or most efficient way to do this?

What if I wanted to keep processing instructions, etc. alone that come
before the root?
Or what if I wanted to drop all non-element(root) stuff out?

I am thinking maybe XmlDocument's ReplaceChild?

Thanks very much.
Nov 12 '05 #1
9 3688
I realize xsl transform is an option. Let's say other than xsl...

"Jiho Han" <ji******@infinityinfo.com> wrote in message
news:u4**************@TK2MSFTNGP09.phx.gbl...
Suppose I have an xml fragment like:

<mother>
<child name="Bob" sex="M"/>
<child name="Jane" sex="F"/>
...
</mother>

If I wanted to replace the <mother> element to <father> element, what is the fastest or most efficient way to do this?

What if I wanted to keep processing instructions, etc. alone that come
before the root?
Or what if I wanted to drop all non-element(root) stuff out?

I am thinking maybe XmlDocument's ReplaceChild?

Thanks very much.

Nov 12 '05 #2
Jiho Han wrote:
Suppose I have an xml fragment like:

<mother>
<child name="Bob" sex="M"/>
<child name="Jane" sex="F"/>
...
</mother>

If I wanted to replace the <mother> element to <father> element, what is the
fastest or most efficient way to do this?


Basically that depends on your application. In fact the most effective
would be customized XmlReader, which reads mother element as father
element. Here is how it could be done with XmlReaderReader
(http://msdn.microsoft.com/library/de...rcreation.asp).
public class MyXmlReader : XmlReaderReader
{
private bool readingMother;

public MyXmlReader(XmlReader r) : base (r){}

public override String Name
{
get { return base.NodeType == XmlNodeType.Element && readingMother?
"father":base.Name; }
}

public override String LocalName
{
get { return base.NodeType == XmlNodeType.Element &&
readingMother?"father":base.LocalName; }
}

public override bool Read ()
{
bool result;
result = base.Read();

if (base.NodeType == XmlNodeType.Element &&
base.Name == "mother")
readingMother = true;
return result;
}
}

And here is a test:

MyXmlReader r = new MyXmlReader(new XmlTextReader("foo.xml"));
//Test it
XmlDocument doc = new XmlDocument();
doc.Load(r);
doc.Save(Console.Out);
--
Oleg Tkachenko [XML MVP, XmlInsider]
http://blog.tkachenko.com
Nov 12 '05 #3
I see.
Are there other options? Would creating a new element and copying all
attributes and the children be an overkill? I guess it would be for a
sizeable document...
Would xslt perform better than the method above?

Now for a specific case - if I were to employ a derived XmlReader -, let's
say I need to validate the same xml document. The correct root element for
the schema would be <father>, so I would want to replace <mother> with
<father> in my derived XmlReader. I am guessing that XmlValidatingReader
would be wrapped around the derived reader like so:

XmlValidatingReader vReader = new XmlValidatingReader(myXmlReader);

So, when doing:

while(vReader.Read())
{
...
}

The XmlValidatingReader would never even see <mother>, correct?

Lastly, if I were not using a derived Reader, what would I use to
replace/add/remove an element or an attribute on the fly? I say on the fly
because I'm guessing you can always use XmlDocument to manipulate it anyway
you want.

Thanks much.
Jiho

"Oleg Tkachenko [MVP]" <oleg@NO!SPAM!PLEASEtkachenko.com> wrote in message
news:O0****************@tk2msftngp13.phx.gbl...
Jiho Han wrote:
Suppose I have an xml fragment like:

<mother>
<child name="Bob" sex="M"/>
<child name="Jane" sex="F"/>
...
</mother>

If I wanted to replace the <mother> element to <father> element, what is the fastest or most efficient way to do this?
Basically that depends on your application. In fact the most effective
would be customized XmlReader, which reads mother element as father
element. Here is how it could be done with XmlReaderReader

(http://msdn.microsoft.com/library/de...-us/cpguide/ht
ml/cpconcustomizedxmlreadercreation.asp).

public class MyXmlReader : XmlReaderReader
{
private bool readingMother;

public MyXmlReader(XmlReader r) : base (r){}

public override String Name
{
get { return base.NodeType == XmlNodeType.Element && readingMother?
"father":base.Name; }
}

public override String LocalName
{
get { return base.NodeType == XmlNodeType.Element &&
readingMother?"father":base.LocalName; }
}

public override bool Read ()
{
bool result;
result = base.Read();

if (base.NodeType == XmlNodeType.Element &&
base.Name == "mother")
readingMother = true;
return result;
}
}

And here is a test:

MyXmlReader r = new MyXmlReader(new XmlTextReader("foo.xml"));
//Test it
XmlDocument doc = new XmlDocument();
doc.Load(r);
doc.Save(Console.Out);
--
Oleg Tkachenko [XML MVP, XmlInsider]
http://blog.tkachenko.com

Nov 12 '05 #4
Jiho Han wrote:
Are there other options? Lots of!
Would creating a new element and copying all
attributes and the children be an overkill? I guess it would be for a
sizeable document...
Would xslt perform better than the method above? Nope. Loading to DOM and manipulating in-memory is rarely effective. The
same for XSLT - input must be loaded as a whole. Basically what is teh
most eeffective depends on many factors, so the best way is to measure.
The XmlValidatingReader would never even see <mother>, correct?
Sure.
Lastly, if I were not using a derived Reader, what would I use to
replace/add/remove an element or an attribute on the fly? I say on the fly
because I'm guessing you can always use XmlDocument to manipulate it anyway
you want.

I'm not aware of any other "on-the-fly" facility in .NET.
--
Oleg Tkachenko [XML MVP, XmlInsider]
http://blog.tkachenko.com
Nov 12 '05 #5
"Oleg Tkachenko [MVP]" <oleg@NO!SPAM!PLEASEtkachenko.com> wrote in message news:<eT**************@TK2MSFTNGP09.phx.gbl>...
Jiho Han wrote:
Are there other options?

Lots of!
Would creating a new element and copying all
attributes and the children be an overkill? I guess it would be for a
sizeable document...
Would xslt perform better than the method above?

I guess one could also use RegExp. It depends whether it is a file
that needs changing or stream (memory representation (infoset)) or
something else...

Miha
Nov 12 '05 #6
So I created a custom reader deriving from XmlTextReader and overrode three
methods/properties:

Name, LocalName, and Read()

I am feeding this class to XmlSerializer.Deserialize method. I have a class
that was generated by xsd.exe and it is able to serialize/deserialize
properly if I give it a proper Stream or TextReader. It's only when I feed
it my custom XmlReader it fails.
However, if I pipe my custom reader into a writer and save the result to a
string or a stream and feed it back into Deserialize everything is working
again.

The error I get is something like:

There is an error in XML document (1, 2). --->
System.InvalidOperationException: <association_update xmlns=''> was not
expected. at
Microsoft.Xml.Serialization.GeneratedAssembly.XmlS erializationReader1.Read4_
association_update()

which I don't understand what it means. <association> is the original root
and <association_update> is the replacement name my custom reader returns.
I don't know where [xmlns=''] part comes from but even if I create an xml
string by hand with the thing, it works. Upon debugging, it seems that the
XmlSerializationReader is calling CreateUnknownNodeException when it sees
<association_update xmlns=''> node. I tried supplying default namespace
value of "" to the XmlSerializer's constructor and that did not work either.

Was I supposed to override some other property/method in XmlTextReader?
What am I missing?

Thanks for your assistance.
Jiho

"Oleg Tkachenko [MVP]" <oleg@NO!SPAM!PLEASEtkachenko.com> wrote in message
news:eT**************@TK2MSFTNGP09.phx.gbl...
Jiho Han wrote:
Are there other options?

Lots of!
Would creating a new element and copying all
attributes and the children be an overkill? I guess it would be for a
sizeable document...
Would xslt perform better than the method above?

Nope. Loading to DOM and manipulating in-memory is rarely effective. The
same for XSLT - input must be loaded as a whole. Basically what is teh
most eeffective depends on many factors, so the best way is to measure.
The XmlValidatingReader would never even see <mother>, correct?


Sure.
Lastly, if I were not using a derived Reader, what would I use to
replace/add/remove an element or an attribute on the fly? I say on the fly because I'm guessing you can always use XmlDocument to manipulate it anyway you want.

I'm not aware of any other "on-the-fly" facility in .NET.
--
Oleg Tkachenko [XML MVP, XmlInsider]
http://blog.tkachenko.com

Nov 12 '05 #7
Jiho Han wrote:
I am feeding this class to XmlSerializer.Deserialize method. I have a class
that was generated by xsd.exe and it is able to serialize/deserialize
properly if I give it a proper Stream or TextReader. It's only when I feed
it my custom XmlReader it fails.


Well, apparently some namespace issue involved? We've been talking only
about renaming root element on the fly, not about modifying namespace.
The samples you have posted had no namespace.
Without seeing your real XML I can suggest nothing.
--
Oleg Tkachenko [XML MVP, XmlInsider]
http://blog.tkachenko.com
Nov 12 '05 #8
Oleg,

Although I can work around this problem, I'd really like to get to the
bottom of this... as to why this happens. Here is a sample of the incoming
xml:

<?xml version="1.0"?>
<association xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<fromid>8c4a969b-2aa4-4679-b170-d9f6441f7c6d</fromid>
<fromobjecttypecode>1</fromobjecttypecode>
<toid>df3f306f-19de-4f50-9784-623bf6693fa8</toid>
<toobjecttypecode>2</toobjecttypecode>
<forwardrelation>Parent</forwardrelation>
<backrelation>Parent</backrelation>
<forwardnotes>aaa</forwardnotes>
<backnotes>bbb</backnotes>
</association>

My derived XmlReader replaces the association root node to
association_create - simply returning association_create in place of
association in Name and LocalName properties. And here is how I
deserialize:
StringReader sr = new StringReader(Association);

EntityReader er = new EntityReader(sr, "association",
EntityReader.Mode.Create, Context);

XmlSerializer serializer = new XmlSerializer(typeof(association_create));

association_create associationObj = serializer.Deserialize(er) as
association_create;

And below is the class generated by XSD that XmlSerializer uses to
deserialize:

[System.Xml.Serialization.XmlRootAttribute(Namespac e="", IsNullable=false)]

public class association_create {
/// <remarks/>

[System.Xml.Serialization.XmlElementAttribute(Form= System.Xml.Schema.XmlSche
maForm.Unqualified)]

public lookupElement fromid;
/// <remarks/>

[System.Xml.Serialization.XmlElementAttribute(Form= System.Xml.Schema.XmlSche
maForm.Unqualified)]

public int fromobjecttypecode;
/// <remarks/>

[System.Xml.Serialization.XmlElementAttribute(Form= System.Xml.Schema.XmlSche
maForm.Unqualified)]

public lookupElement toid;
/// <remarks/>

[System.Xml.Serialization.XmlElementAttribute(Form= System.Xml.Schema.XmlSche
maForm.Unqualified)]

public int toobjecttypecode;
/// <remarks/>

[System.Xml.Serialization.XmlElementAttribute(Form= System.Xml.Schema.XmlSche
maForm.Unqualified)]

public string forwardrelation;
/// <remarks/>

[System.Xml.Serialization.XmlElementAttribute(Form= System.Xml.Schema.XmlSche
maForm.Unqualified)]

public string backrelation;
/// <remarks/>

[System.Xml.Serialization.XmlElementAttribute(Form= System.Xml.Schema.XmlSche
maForm.Unqualified)]

public string forwardnotes;
/// <remarks/>

[System.Xml.Serialization.XmlElementAttribute(Form= System.Xml.Schema.XmlSche
maForm.Unqualified)]

public string backnotes;

}

I really appreciate your help on this. Thanks.

Jiho
"Oleg Tkachenko [MVP]" <oleg@NO!SPAM!PLEASEtkachenko.com> wrote in message
news:OY**************@TK2MSFTNGP10.phx.gbl...
Jiho Han wrote:
I am feeding this class to XmlSerializer.Deserialize method. I have a class that was generated by xsd.exe and it is able to serialize/deserialize
properly if I give it a proper Stream or TextReader. It's only when I feed it my custom XmlReader it fails.


Well, apparently some namespace issue involved? We've been talking only
about renaming root element on the fly, not about modifying namespace.
The samples you have posted had no namespace.
Without seeing your real XML I can suggest nothing.
--
Oleg Tkachenko [XML MVP, XmlInsider]
http://blog.tkachenko.com

Nov 12 '05 #9
Jiho Han wrote:
Although I can work around this problem, I'd really like to get to the
bottom of this... as to why this happens. Here is a sample of the incoming
xml:


Dunno, works for me. Here is foo.xml file:

<association xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>

The code:
class Class1
{
[STAThread]
static void Main(string[] args)
{
XmlSerializer ser = new XmlSerializer(typeof(association_create));
association_create cr = (association_create)ser.Deserialize(new
MyXmlReader(new XmlTextReader("foo.xml")));
Console.WriteLine(cr);
}
}
[System.Xml.Serialization.XmlRootAttribute(Namespac e="", IsNullable=false)]

public class association_create
{
}

public class MyXmlReader : XmlReaderReader
{
private bool readingAssociation;

public MyXmlReader(XmlReader r) : base (r){}

public override String Name
{
get { return base.NodeType == XmlNodeType.Element &&
readingAssociation? "association_create":base.Name; }
}

public override String LocalName
{
get { return base.NodeType == XmlNodeType.Element &&
readingAssociation?"association_create":base.Local Name; }
}

public override bool Read ()
{
bool result;
result = base.Read();

if (base.NodeType == XmlNodeType.Element &&
base.Name == "association")
readingAssociation = true;
return result;
}

}

--
Oleg Tkachenko [XML MVP, XmlInsider]
http://blog.tkachenko.com
Nov 12 '05 #10

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

Similar topics

3
by: Christian | last post by:
HI NG, AFAIK, a dtd names the root element, i.e. <!DOCTYPE test SYSTEM "SomeURL"> must be followed by the root element named "test". However, Xerces 2.4.0 does not complain, if SomeURL...
3
by: Sascha Kerschhofer | last post by:
If I define more than one element "globally" in an XML schema, is there any hint which one is the actual root element for any instance document? e.g. <xs:schema...
5
by: Paul Nations | last post by:
I'm in a real pickle. I've inherited a project with major problems. It receives encrypted XML files from a website not under my control (so I can't modify the web app) for insertion into a...
28
by: Andy Dingley | last post by:
What specifies the permitted root element(s) for a document ? HTML, SGML, XHTML or XML ? Valid HTML documents need to have a well-known DTD and a doctypedecl in each document like this:...
16
by: TT (Tom Tempelaere) | last post by:
Hi all, I created an XSD to define the structure of an XML file for my project. I made an XML file linked to the XSD using XmlSpy. The problem is that if I read the file using .NET XmlDocument...
4
by: Hone | last post by:
I'm trying to serialize/deserialize the XML for an RSS 1.0 Feed (i.e. RDF) and the root element, as required by the standard, looks like this: <rdf:RDF ...> </rdf:RDF> However, I've tried...
8
by: VK | last post by:
Can be multiple instances of element used as the root element? That's a curly way of asking, but I did not come up with a better sentence, sorry. What I mean is with a document like: <?xml...
0
by: Dave Hill | last post by:
Forgive a newbie question. I'm learning the .NET XML environment. In the walkthrough on using XML designer to create an xsd, there is no discussion of the root element of the target xml document....
0
by: icesign | last post by:
I know that the selector of these elements has a scope relative to the element being declared, but maybe there is a way to get beyond bounds of this scope or maybe just a way to extend base element?...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.