[英]PowerShell - xpath for Case Insensitive XML attribute name
I have a XML where the attribute names can be combinations of lower-case and upper-case letters.我有一个 XML ,其中属性名称可以是小写和大写字母的组合。 In the below example, 'datasource' attribute can have any number of lowercase and uppercase letters.
在下面的示例中,'datasource' 属性可以有任意数量的小写和大写字母。
I need to fetch those nodes where the 'datasource' is XML.我需要获取“数据源”为 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.
translate(), lower-case() 有几个例子,但它们不适合我的场景。
[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这将返回
System.Xml.XmlElement
节点数组
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()
.但是通过结合 PowerShell 代码和 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.当然,您可以手动编写翻译 function,尤其是在要翻译的字符串基本上是硬编码的情况下。
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.因为这仅限于预定义的字母,并且除非您明确包含重音字符,否则它会失败,这很快就会变得笨拙。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.