SelectNodes with XPath ignoring cases in node names
Solution 1
We may convert xml and our variables to lower case.
string value = "aBc";
XmlNode xmlnode = xmldoc.SelectSingleNode(string.Format("/some/path/add[translate(@key, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = '{0}']", value.ToLower()));
Solution 2
Just use:
*[translate(name(), 'APPLICATION', 'application')='application']
/forms/action/form/@uid
This selects the wanted attribute correctly in all cases when the current (initial context) node has a child with name, that is any capitalization of the string "application".
XSLT - based verification:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:value-of select=
"*[translate(name(), 'APPLICATION', 'application')='application']
/forms/action/form/@uid"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the following XML document:
<aPPliCatioN>
<forms>
<action>
<form uid="xyz"/>
</action>
</forms>
</aPPliCatioN>
the wanted node is selected and its string value is copied to the output:
xyz
Explanation:
Proper use of the standard XPath functions name()
and translate()
.
Solution 3
First of all I want to mention that xml is case sensitive, so Application means something else then application, looks to me this should be fixed in the code that generates this xml but if you have no control over that maybe try something like this as your xpath:
"Application/forms/action/form/@uid | application/forms/action/form/@uid"
The | operator will combine the node-sets that are returned from both xpath's in this case it will be one or the other
Solution 4
If the root element is the only element where the case of letters can change then you should simply do e.g.
XmlDocument doc = new XmlDocument();
doc.Load("input.xml");
XmlNode nodex= oXMLDoc1.DocumentElement.SelectSingleNode("forms/action/form/@uid");
as already suggested in a comment.
With XDocument you would do e.g.
XDocument doc = XDocument.Load("input.xml");
doc.Root.Element("forms").Element("action").Element("form").SetAttributeValue("uid", "UniqueIDx");
[edit] A comment claims the first example path throws an exception, here is a complete sample that does not throw an exception for me and uses the same path a posted before:
string xml = @"<application>
<forms>
<action type=""update"">
<form uid="""" >
</form>
</action>
</forms>
</application>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNode nodex = doc.DocumentElement.SelectSingleNode("forms/action/form/@uid");
nodex.Value = "UniqueIDx";
doc.Save(Console.Out);
VSP
Updated on August 18, 2021Comments
-
VSP over 2 years
I have a problem similar to the question SelectNodes with XPath ignoring cases but in my case the uppercase/lowercase problem is in the node with the name 'application' (Sometimes is 'Application' other times 'application').
How would i apply the solution of the other post? or a different one applies in this case?
xml:
<?xml version="1.0" encoding="utf-16" ?> <application> <forms> <action type="update"> <form uid="" > </form> </action> </forms> </application>
In C# 3.5:
XmlNode nodex= oXMLDoc1.SelectSingleNode("Application/forms/action/form/@uid") nodex.Value="UniqueIDx";//nodex is null :S
-
VSP almost 12 yearsYep knew the xml is case sensitive but effectively the xml generated depended on a third party so this was needed... Your method works fine but i wanted to know if maybe with LINQ to XML or getting the first node by possition would be more optimal as in this solution the code tries to get both nodes...
-
VSP almost 12 yearsTrying your first example failed with a nullreferenceexception, worked instead with: */forms/action/form/@uid
-
Martin Honnen almost 12 yearsWith the sample you posted I think my suggestion should work, I will edit my post to show a complete example that does not throw an exception for me.
-
VSP almost 9 yearsThanks for the answer, as this is the most generic one so it can be applied in other situations
-
Varadha31590 almost 8 yearswhat does the "/some/path/add" means ??