当前位置: 首页 > 知识库问答 >
问题:

使用Powershell解析XML文件

凤安然
2023-03-14

我试图解析一个xml文件,但似乎无法提取我想要的部分。xml文件是为自己开发的系统准备的,我对它的布局没有任何控制权。

文件如下所示:

$doc = [xml]@'
<?xml version="1.0" encoding="utf-8"?>
<rbacx >
    <namespace namespaceName="Team Name" namespaceShortName="ABC"/>
    <attributeValues>
        <attributeValue id="Role=Administrator">
            <value><![CDATA[Administrator]]></value>
            <attributes>
                <attribute name="Glossary">
                    <attributeValues>
                        <attributeValue><value><![CDATA[Administrator (service accounts)]]></value></attributeValue>
                    </attributeValues>
                </attribute>
            </attributes>
        </attributeValue>
        <attributeValue id="Role=Operator">
            <value><![CDATA[Operator]]></value>
            <attributes>
                <attribute name="Glossary">
                    <attributeValues>
                        <attributeValue><value><![CDATA[Operator (all accounts)]]></value></attributeValue>
                    </attributeValues>
                </attribute>
            </attributes>
        </attributeValue>
    </attributeValues>
    <accounts>
        <account id="FRED">
            <name><![CDATA[FRED@xyz.com]]></name>
            <endPoint>ABC</endPoint>
            <domain>ABC</domain>
            <comments/>
            <attributes>
                <attribute name="AppBoRID">
                    <attributeValues>
                        <attributeValue><value><![CDATA[FRED]]></value></attributeValue>
                    </attributeValues>
                </attribute>
                <attribute name="Role">
                    <attributeValues><attributeValueRef id="Role=Operator"/></attributeValues>
                </attribute>
            </attributes>
        </account>
        <account id="BARNEY">
            <name><![CDATA[BARNEY@xyz.com]]></name>
            <endPoint>ABC</endPoint>
            <domain>ABC</domain>
            <comments/>
            <attributes>
                <attribute name="AppBoRID">
                    <attributeValues>
                        <attributeValue><value><![CDATA[BARNEY]]></value></attributeValue>
                    </attributeValues>
                </attribute>
                <attribute name="Role">
                    <attributeValues><attributeValueRef id="Role=Administrator"/></attributeValues>
                </attribute>
            </attributes>
        </account>
        <account id="NonPeopleID_CC1234">
            <name><![CDATA[WILMA@xyz.com]]></name>
            <endPoint>ABC</endPoint>
            <domain>ABC</domain>
            <comments/>
            <attributes>
                <attribute name="appUserName">
                    <attributeValues>
                        <attributeValue><value><![CDATA[WILMA]]></value></attributeValue>
                    </attributeValues>
                </attribute>
                <attribute name="CostCentre">
                    <attributeValues>
                        <attributeValue><value><![CDATA[1234]]></value></attributeValue>
                    </attributeValues>
                </attribute>
                <attribute name="Bank_Number">
                    <attributeValues>
                        <attributeValue><value><![CDATA[0000]]></value></attributeValue>
                    </attributeValues>
                </attribute>
                <attribute name="Directory">
                    <attributeValues>
                        <attributeValue><value><![CDATA[XYZ]]></value></attributeValue>
                    </attributeValues>
                </attribute>
                <attribute name="Role">
                    <attributeValues><attributeValueRef id="Role=Administrator"/></attributeValues>
                </attribute>
            </attributes>
        </account>
        <account id="NonPeopleID_CC1234">
            <name><![CDATA[BETTY@xyz.com]]></name>
            <endPoint>ABC</endPoint>
            <domain>ABC</domain>
            <comments/>
            <attributes>
                <attribute name="appUserName">
                    <attributeValues>
                        <attributeValue><value><![CDATA[BETTY]]></value></attributeValue>
                    </attributeValues>
                </attribute>
                <attribute name="CostCentre">
                    <attributeValues>
                        <attributeValue><value><![CDATA[1234]]></value></attributeValue>
                    </attributeValues>
                </attribute>
                <attribute name="Bank_Number">
                    <attributeValues>
                        <attributeValue><value><![CDATA[0000]]></value></attributeValue>
                    </attributeValues>
                </attribute>
                <attribute name="Directory">
                    <attributeValues>
                        <attributeValue><value><![CDATA[XYZ]]></value></attributeValue>
                    </attributeValues>
                </attribute>
                <attribute name="Role">
                    <attributeValues><attributeValueRef id="Role=Operator"/></attributeValues>
                </attribute>
            </attributes>
        </account>
    </accounts>
</rbacx>

'@

我希望得到这样的输出——

Name            Role
FRED            Operator
BARNEY          Administrator
WILMA           Administrator
BETTY           Operator

我能得到name@domain因此——

$Doc.rbacx.accounts.account.name 

where it returns - 

#cdata-section
--------------
FRED@xyz.com  
BARNEY@xyz.com
WILMA@xyz.com 
BETTY@xyz.com  

我可以用这个获得所有的值属性-

$Doc.rbacx.accounts.account.attributes.attribute.attributevalues.attributevalue.value 

where it returns - 

#cdata-section
--------------
FRED          
BARNEY        
WILMA         
1234          
0000          
XYZ           
BETTY         
1234          
0000          
XYZ   

我似乎无法返回与用户相关联的角色。我想应该是这样的——

$Doc.rbacx.accounts.account.attributes.attribute.attributevalues.attributevalue.attributeValueRef 

然而,这并不返回任何东西。

关于如何获得用户的任何想法

共有2个答案

韩弘阔
2023-03-14

Arjabbar的答案非常棒,除非你使用的是5.1,其中不支持??语法。我相信有一种更清洁的检查方法,但这将实现您的结果。如果帐户具有应用程序用户名,它将使用该名称,否则它将使用该 ID。

$doc.SelectNodes("//accounts/account") | foreach {
    $name = if($appusername = $_.SelectSingleNode('attributes/attribute[@name="appUserName"]//value').'#cdata-section')
    {
        $appusername
    }
    else
    {
        $_.id
    }
    [PSCustomObject]@{
        Name = $name
        Role = $_.SelectSingleNode('attributes/attribute[@name="Role"]//attributeValueRef/@id').value.Split('=') | select -last 1
    }
}

Name   Role         
----   ----         
FRED   Operator     
BARNEY Administrator
WILMA  Administrator
BETTY  Operator 
严信瑞
2023-03-14

一旦您熟悉了XPath,剩下的也不会太糟糕。此外,更难的是角色名称是role=Operator,而不仅仅是Operator。因此,您必须对attributeValueRef节点上的属性id,进行字符串拆分。最后你会得到这样的东西。

编辑:合并运算符仅在Powershell 7中运行

在这里可以找到许多针对您的PowerShell版本的替代方案。

$doc.SelectNodes("//accounts/account") | % { [pscustomobject]@{Name = $_.SelectSingleNode('attributes/attribute[@name="appUserName"]//value').'#cdata-section' ?? $_.id; Role = $_.SelectSingleNode('attributes/attribute[@name="Role"]//attributeValueRef/@id').value.Split('=')[1] } }

输出是< code>[PSCustomObject]。运行它将在控制台中显示您的输出,但是如果您真的需要它只是一个字符串,您可以通过< code>Out-String或< code>Format-Table来处理它。

 类似资料:
  • 问题内容: 我如何在Java或C中使用vtd-xml解析如下的xml文件? 任何帮助,将不胜感激。 谢谢 问题答案: 我想其中有些取决于您要如何解析文件。 这是一个“非生产”示例,其中使用了一些有用的技术,包括: XPath选择(此处仅使用“ / *”) 浏览所有同级节点 通过子节点向下看 使用AutoPilot将节点属性提取到地图中 希望能帮助到你 产生以下输出: 添加带有AutoPilot循环

  • 如何在java或C中使用vtd xml解析如下xml文件? 任何帮助都将不胜感激。 谢谢

  • 问题内容: 我想解析以下网址:http : //eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi? db= nucleotide& id= 224589801 结果,我想出了以下方法: 通过这种方法,我可以获取Item节点的值,但不能获取其任何属性。我尝试使用NamedNodeMap与getAttribute()进行实验,但仍然无济于事。 为什

  • 为了在巨大的xml文件中执行XPATH查询,我阅读了许多喜欢VTD-xml的文章,因此我复制了这些文章中的代码: 但当我运行它时没有结果,所以这意味着XML文件没有映射到内存中。。。我的问题是如何在VTD-xml中强制映射xml文件?

  • 问题内容: 我需要能够使用JavaScript解析XML。XML将在变量中。我宁愿不使用jQuery或其他框架。 我已经看过了,XML> jQuery阅读。 问题答案: 从这个问题的20分钟前的最后一个问题中longitude-to-address),我猜测您正在尝试解析(读取和转换)通过使用GeoNames的FindNearestAddress找到的XML。 如果您的XML在名为的字符串变量中,

  • 我有一个XML文件,其中包含大量员工记录(比如高达1M),如下所示: 我使用JAXB将员工记录映射到以下Java对象: XML的内容不能被更改,并且给定这个XML,我如何使用JAXB将每个员工XML记录解封给员工对象,以便我可以逐个处理它?