Click here to Skip to main content
15,895,142 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
How do I check for any unbalanced set of parentheses inside a node using LINQ-to-XML, for example
XML
<?xml version="1.0"?>
    <root>
    	<child1>Anything goes <a>(here</a>) and <bb>(there)</bb>!</child1>
    	<child2>Whatever <a>goes (around)</a> <bb>comes around()</bb> and (<a>that is)</a> a fact.</child1>
    </root>

In the above sample xml, the node <a>(here</a> contains only a opening parentheses inside the node and the closing parentheses is outside the node, in that case I want to re-position that opening parentheses to just before the <a> node as (<a>here</a>) and the same logic for any node like (<a>that is)</a> should be replaced as (<a>that is</a>) and <a>goes (around)</a> should remain unchanged as it contains a complete set of opening and closing parentheses, however <bb>(there)</bb> should also be changed to (<bb>there</bb>) as both the opening and closing parentheses are positioned immediately after and before the nodes.
Can anybody help!!

What I have tried:

I'm clueless how to do this to be honest
XDocument xml = XDocument.Load(@"D:\test.xml");
var targetnodes=from x in xml.Descendants("a")
                where ????

Also, here are some other types for better understanding
<bb>(statistical moments of the 1(st) - 4(th) (order))</bb>
(<bb>statistical moments of the 1(st) - 4(th) (order))</bb>
<bb>(statistical moments of the 1(st) - 4(th) (order)</bb>)
<bb>((statistical moments) of the 1(st) - 4(th) (order)</bb>)
should be
(<bb>statistical moments of the 1(st) - 4(th) (order)</bb>)
(<bb>statistical moments of the 1(st) - 4(th) (order)</bb>)
(<bb>statistical moments of the 1(st) - 4(th) (order)</bb>)
(<bb>(statistical moments) of the 1(st) - 4(th) (order)</bb>)
Posted
Updated 12-Mar-18 5:24am
v3

1 solution

One strategy I used some time ago for similar types of things:

You need to push/pop things from a stack - actually, possibly more than one stack.

For elements: you push the name of the element on the stack. When a closing element comes up, compare it to the top of the stack and it must match (and if it does, pop it).
This is necessary so that paring occurs within an element.

Now, for the parenthesis: they, like braces, etc., must occur in pairs between elements (the push/pop above). If you use the same stack, whenever you come across a paren, compare it to the top element. If you've just gotten a closing paren then the top element should be an opening paren. If not, push the new paren (they're nesting). Eventually, you'll reach the closing element and there should be no paren's left. Same test as in paragraph, above.


 
Share this answer
 
Comments
Member 12692000 12-Mar-18 12:18pm    
Can you show some code please?
W Balboos, GHB 12-Mar-18 13:09pm    
Google is your friend (C# stacks)
https://www.dotnetperls.com/stack - for example

There are a few basic commands push, pop, peek -
You need to do the comparison based upon whatever type you are trying to compare. In your case, the type you'd most likely use is string - and depending upon your source, you can make comparisons case sensitive or not (human or machine generated).

Stacks are really powerful and important tools - essential for a parser - which is what you're making.

You push 'opening' items, be that tags, parenthesis, quotes, whatever. For things like tags or closing parenthesis, peek at the top item on the stack it must match if things are to close in the order opened. If it matches, pop it off the stack (it's closed and thus complete). If it doesn't match - you have found your problem.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900