I have a XML where the attribute names can be combinations of lower-case and upper-case letters. In the below example, 'datasource' attribute can have any number of lowercase and uppercase letters.
I need to fetch those nodes where the 'datasource' is XML. I have searched all over the internet, but could not find any solution for this. Several examples are there for translate(), lower-case() but they don't fit my scenario.
[xml] $GM_ProcessXML =@'
<Process>
<Parameter Name="Parameter1" Datasource="XML"><![CDATA[Sujeet]]></Parameter>
<Parameter Name="Parameter2" DataSource="XML"><![CDATA[Padhi]]></Parameter>
<Parameter Name="Parameter3" DatASource="XML"><![CDATA[Padhi]]></Parameter>
<Parameter Name="Parameter4" datASource="XML"><![CDATA[Padhi]]></Parameter>
<Node>
<Node1 Name="Node1" Datasource="XML"><![CDATA[Sujeet]]></Node1>
<Node2 Name="Node2" DataSource="XML"><![CDATA[Padhi]]></Node2>
<Node3 Name="Node3" DatASource="XML"><![CDATA[Padhi]]></Node3>
<Node4 Name="Node4" datASource="XML"><![CDATA[Padhi]]></Node4>
</Node>
</Process>
'@
$XPath = "//*[@datasource='XML']"
$Nodes = $GM_ProcessXML.SelectNodes($XPath)
$Nodes
You could also use the case-insensitive dot notation like this:
$Nodes = $GM_ProcessXML.Process.Parameter | Where-Object { $_.DAtaSourcE -eq 'xML' }
This will return an array of System.Xml.XmlElement
nodes
Short of modifying the files:
[xml]$GM_ProcessXML = @'
<Process>
<Parameter Name="Parameter1" Datasource="XML"><![CDATA[Sujeet]]></Parameter>
<Parameter Name="Parameter2" DataSource="XML"><![CDATA[Padhi]]></Parameter>
<Parameter Name="Parameter3" DatASource="XML"><![CDATA[Padhi]]></Parameter>
<Parameter Name="Parameter4" datASource="XML"><![CDATA[Padhi]]></Parameter>
<Node>
<Node1 Name="Node1" Datasource="XML"><![CDATA[Sujeet]]></Node1>
<Node2 Name="Node2" DataSource="XML"><![CDATA[Padhi]]></Node2>
<Node3 Name="Node3" DatASource="XML"><![CDATA[Padhi]]></Node3>
<Node4 Name="Node4" datASource="XML"><![CDATA[Padhi]]></Node4>
</Node>
</Process>
'@ -replace 'datasource','datasource'
$XPath = "//*[@datasource='XML']"
$Nodes = $GM_ProcessXML.SelectNodes($XPath)
$Nodes
Name datasource #cdata-section
---- ---------- --------------
Parameter1 XML Sujeet
Parameter2 XML Padhi
Parameter3 XML Padhi
Parameter4 XML Padhi
Node1 XML Sujeet
Node2 XML Padhi
Node3 XML Padhi
Node4 XML Padhi
So, on the face of it, you are out of luck. But there is a work-around by combining PowerShell code and XPath translate()
.
[xml] $GM_ProcessXML =@'
<Process>
<Parameter Name="Parameter1" Datasource="XML"><![CDATA[Sujeet]]></Parameter>
<Parameter Name="Parameter2" DataSource="XML"><![CDATA[Padhi]]></Parameter>
<Parameter Name="Parameter3" DatASource="XML"><![CDATA[Padhi]]></Parameter>
<Parameter Name="Parameter4" datASource="XML"><![CDATA[Padhi]]></Parameter>
<Node>
<Node1 Name="Node1" Datasource="XML"><![CDATA[Sujeet]]></Node1>
<Node2 Name="Node2" DataSource="XML"><![CDATA[Padhi]]></Node2>
<Node3 Name="Node3" DatASource="XML"><![CDATA[Padhi]]></Node3>
<Node4 Name="Node4" datASource="XML"><![CDATA[Padhi]]></Node4>
</Node>
</Process>
'@
$attributeName = 'DataSource'
$lc = $attributeName.ToLowerInvariant() # -> 'datasource'
$uc = $attributeName.ToUpperInvariant() # -> 'DATASOURCE'
$XPath = "//*[@*[translate(name(), '$uc', '$lc') = '$lc'] = 'XML']"
# -> //*[@*[translate(name(), 'DATASOURCE', 'datasource') = 'datasource'] = 'XML']
$Nodes = $GM_ProcessXML.SelectNodes($XPath)
Of course you can write the translate function by hand, especially in cases where the string to translate is basically hard-coded.
But this approach is generic, so you can also use it to search case-insensitively for any user-provided/dynamic value, eg:
$value = 'sujeet' # as the user has entered it
$lc = $value.ToLowerInvariant()
$uc = $value.ToUpperInvariant()
$XPath = "//Parameter[translate(., '$uc', '$lc') = '$lc']"
# -> //Parameter[translate(., 'SUJEET', 'sujeet') = 'sujeet']
This is a lot better than the often-proposed
translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')
since that is limited to pre-defined alphabets, and fails for eg accented characters unless you explicitly include them, which quickly becomes unwieldy.
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.