简体   繁体   中英

XML document got already a DocumentElement node when i try to load XMLReader object into XMLDocument

I want to create in an app - coded with C# - a copy of the actual element of a XMLReader object by using a XMLDocument instance.

The purpose is to get a copy of the actual reader element, so i can read the inner XML from the actual XML element without moving in the original reader.

When i try to load the reader into the XMLDocument i get the error "The document already has a 'DocumentElement' node.".

Any help would be appreciated.

XmlDocument xmlDocument = new XmlDocument();
MemoryStream streamFromReader = new MemoryStream();
xmlDocument.Load(reader); //Here i get the error
xmlDocument.Save(streamFromReader);
streamFromReader.Position = 0;
XmlReader copyReader = XmlReader.Create(streamFromReader);
sb.Append(copyReader.ReadInnerXml());
copyReader.Close();

The problem is that the reader is already positioned somewhere in the middle of the XML file, eg:

<Parent>            <---- Position of the reader
  <Child></Child>
  <Child></Child>
</Parent>
<Parent>
  <Child></Child>
  <Child></Child>
</Parent>

The Load method starts to read the current node and also reads the siblings of the node. This leads to an invalid XML structure, because the document can only have one root element. The docs describe this behavior in the remarks section.

As for the original purpose of the code, I understand you want to perform a Peek (check the contents without advancing the reader) on the XmlReader . There are limited options to achieve this because an XmlReader operates forward-only. The answers to this question describe some options on how to read from an XmlReader without advancing it.

The answer of Markus helped me to get to the solution.

When the XMLReader is getting to an element which has subitems, i must get first the actual position within the file using the interface IXmlLineInfo.

IXmlLineInfo lineInfo = (IXmlLineInfo)reader;
int lineNumber = lineInfo.LineNumber;
int linePosition = lineInfo.LinePosition;

Then i create an instance of XmlTextReader, which reads the file to that position.

When the reminded position was arrived, the XmlTextReader contains the element and i can get the inner XML from it.

Stream stream = new MemoryStream(myFile.FileBytes);
XmlTextReader textReader = new XmlTextReader(stream);
while (textReader.LineNumber < lineNumber)
{
    textReader.Read();
}
string innerXml = textReader.ReadInnerXml());
textReader.Close();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM