9
votes

I'm trying to use C#'s XmlReader on a large series of XML files, they are all properly formatted except for a few select ones (unfortunately I'm not in a position to have them changed, because it would break a lot of other code).

The errors only come from one specific part of the these affronting XML files and it's ok to just skip them but I don't want to stop reading the rest of the XML file.

The bad parts look like this:

 <InterestingStuff>
  ...
    <ErrorsHere OptionA|Something = "false" OptionB|SomethingElse = "false"/>
    <OtherInterestingStuff>
    ...
    </OtherInterestingStuff>
</InterestingStuff>

So really if I could just ignore invalid tags, or ignore the pipe symbol then I would be ok.

Trying to use XmlReader.Skip() when I see the name "ErrorsHere" doesn't work, apparently it already reads a bit ahead and throws the exception.

TLDR: How do I skip so I can read in the XML file above, using the XmlReader?

Edit:

Some people suggested just replacing the '|'-symbol, but the idea of XmlReader is to not load the entire file but only traverse parts you want, since I'm reading directly from files I can not afford the read in entire files, replace all instances of '|' and then read parts again :).

3
replacing | sign before loading a reader with - could solve the problem - Prashant Lakhlani
How are you reading the info into the XmlReader? Are you reading from stream? - Jethro
if you know the error in advance, can't you patch the content of the source before parsing it ? But in a general manner, you should correct the source xml.... or don't call it XML (I imagine you are dependant of someone else... ?) - Steve B
Good suggestions, but I don't want to read in the entire file (hence why I use XmlReader and not XmlDocument.Load()) because this could be costly and I don't need all the info in the files. To clarify I read directly from disk using XmlReader.Creat(filepath) and yes I'm depending on other people, so I can't do anything about the source. - Roy T.
+1 Steve B - XmlReader reads Xml, so convert the non-Xml input to valid Xml in an isolated method, keeping the rest of your code clean. - C.Evenhuis

3 Answers

4
votes

I've experimented a bit with this in the past.

In general the input simply has to be well-formed. An XmlReader will go into an unrecoverable error-state when the basic XML rules are broken. It is easy to avoid schema-validation but that's not relevant here.

Your only option is to clean the input, that can be done in a streaming manner (custom Stream or TextReader) but that will require a light form of parsing. If you don't have pipe-symbols in valid positions it's easy.

1
votes

XmlReader is strict. Any non-conformance, it will error.

So no, you can't do that unless you write your own xml implementation. Fixup on the malformed data is probably easier.

1
votes

Once I had a similar situation (with HTML files, not XML files). But I ended up using regular expression for each HTML file before entering it into my operation pipeline, to delete malformed parts. It came handy and was easier than struggling with the API. :)