I have a quite big XML output from an application. I need to process it with my program and then feed it back to the original program. There are pieces in this XML which nee
If you're still having problems with this, it may be because you are using AND with your RegexOptions instead of OR.
This code is wrong and will pass zero as the second parameter to the constructor:
Regex regExp = new Regex(@"<sys:customtag(.*?)Processtart(.*?)/>(.*?)<sys:customtag (.*?)Procesend(.*?)/>",
RegexOptions.Multiline & RegexOptions.IgnorePatternWhitespace & RegexOptions.CultureInvariant);
This code is correct (as far as using multiple RegexOptions flags):
Regex regExp = new Regex(@"<sys:customtag(.*?)Processtart(.*?)/>(.*?)<sys:customtag (.*?)Procesend(.*?)/>",
RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace | RegexOptions.CultureInvariant);
RegExp is a poor tool for xml... could you not juts load it into an XDocument / XmlDocument and use xpath? If you clarify the modifications you want to make, I expect we can fill in the blanks... namespaces are probably the main thing to make it complex in this case, so we just need to use an XmlNamespaceManager
.
Here's an example that is, granted, more complex than just a regex - however, I would expect it to cope a lot better with the nuances of xml:
string xml = @"<foo xmlns:sys=""foobar""><bar/><bar><sys:customtag sys:sid=""1"" sys:type=""Processtart"" />
<sys:tag>value</sys:tag>
here are some other tags
<sys:tag>value</sys:tag>
<sys:customtag sys:sid=""1"" sys:type=""Procesend"" /></bar><bar/></foo>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNamespaceManager mgr = new XmlNamespaceManager(new NameTable());
mgr.AddNamespace("sys", "foobar");
var matches = doc.SelectNodes("//sys:customtag[@sys:type='Processtart']", mgr);
foreach (XmlElement start in matches)
{
XmlElement end = (XmlElement) start.SelectSingleNode("following-sibling::sys:customtag[@sys:type='Procesend'][1]",mgr);
XmlNode node = start.NextSibling;
while (node != null && node != end)
{
Console.WriteLine(node.OuterXml);
node = node.NextSibling;
}
}
The regex char "." never matches a newline, even with MultiLine
option is set.
instead, you should use [\s\S]
or other combination with matches anything.
The MultiLine
option only modifies the behaviour of ^ (begin-of-line instead fo begin-of-string) and $ (end-of-line instead of end-of-string)
BTW: Indeed, regex is not the right way to scan an HTML...
i believe the option to use is RegexOptions.Singleline
instead of RegexOptions.Multiline
(src). allowing (.) to match newlines should work in your case.
...the mode where the dot also matches newlines is called "single-line mode". This is a bit unfortunate, because it is easy to mix up this term with "multi-line mode". Multi-line mode only affects anchors, and single-line mode only affects the dot ... When using the regex classes of the .NET framework, you activate this mode by specifying RegexOptions.Singleline, such as in Regex.Match("string", "regex", RegexOptions.Singleline).