【问题标题】:How do I find this xpath node? One of the elements has periods, and one of the elements doesn't have a key如何找到这个 xpath 节点?其中一个元素有句点,而其中一个元素没有键
【发布时间】:2021-12-24 06:24:33
【问题描述】:

我是一个 XML/PowerShell 菜鸟,所以请原谅任何不正确的术语使用。

这是我试图操作的 XML:

<configuration>
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=" >
            <section name="DatabaseUpdate.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>
    <userSettings>
        <DatabaseUpdate.Properties.Settings>
            <setting name="DBConString" serializeAs="String">
                <value></value>
            </setting>
            <setting name="ScriptPath" serializeAs="String">
              <value></value>
            </setting>
        </DatabaseUpdate.Properties.Settings>
    </userSettings>
</configuration>

在整个项目中,我已经能够使用 powershell 来修改类似的配置(使用 Azure DevOps)。我使用这种通用格式(与上述配置无关):

    $node=$xml.SelectNodes("configuration/appSettings/add[@key='SMTPUSER']")
    $node.SetAttribute("value", "$(SMTPUSER)")

但是,由于value 的放置,我无法使其工作(与上述配置相关):

$node=$xml.SelectNodes("configuration/userSettings/DatabaseUpdate.Properties.Settings/setting[@name='ScriptPath']")
$node.value="$(System.DefaultWorkingDirectory)/extracted/DBScripts/artefacts_Risk/"

我找到了这个链接:Finding Elements with Period in Name,它帮助我创建了这个:

$node=$xml.SelectNodes("//configuration/userSettings/*[local-name()='DatabaseUpdate.Properties.Settings']/setting[@name='ScriptPath']")
    $node.value="$(System.DefaultWorkingDirectory)/extracted/DBScripts/artefacts_Risk/"

我了解在这两个示例中选择值的方式不同,但我已经为第一个脚本尝试了两种方式,并且出现了相同的错误。

两个版本都以失败告终: The property 'value' cannot be found on this object. Verify that the property exists and can be set.

完整的错误是:

The property 'value' cannot be found on this object. Verify that the property exists and can be set.
At C:\azagent\A4\_work\_temp\500556f4-6c37-4021-972b-f665fa907911.ps1:16 char:1
+ $node.value="data source=ipaddress;initial catalog=dbname_ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : PropertyAssignmentException
 
##[error]PowerShell exited with code '1'.

如果它很重要,这里是此任务的完整 powershell 脚本:

- powershell: |
    dir
    Write-Host "Verify DB Connection String is Accurate"
    if("$(EzAcquireConStr)" -like '*risk*') {
          # Write-Host 'Your string contains the word world'
    } else {
          Write-Host 'Default Connection string does not contain word risk, failing pipeline'
          exit 1
    }
    Write-Host "Manipulate Config to match repo's DBScripts"
    $xmlFileName = "$(System.DefaultWorkingDirectory)/DatabaseUpdate/DatabaseUpdate.exe.config"
    $xml=New-Object XML
    $xml.Load($xmlFileName)
    $node=$xml.SelectNodes("configuration/userSettings/*[local-name()='DatabaseUpdate.Properties.Settings']/setting[@name='DBConString']")
    $node.value="$(EzAcquireConStr)"
    $node=$xml.SelectNodes("configuration/userSettings/*[local-name()='DatabaseUpdate.Properties.Settings']/setting[@name='ScriptPath']")
    $node.value="$(System.DefaultWorkingDirectory)/extracted/DBScripts/app/"
    $xml.Save($xmlFileName)
    Write-Host "Run DB Update Using above criteria"
    & $(System.DefaultWorkingDirectory)/DatabaseUpdate/DatabaseUpdate.exe
    Write-Host "If DB Update Errors, fail pipeline"
    if ($lastexitcode -ne 0) {
      exit $LASTEXITCODE
    }
  displayName: 'Inject DBScripts Path for Tool'

【问题讨论】:

    标签: xml powershell xpath


    【解决方案1】:

    $node=$xml.SelectNodes("configuration/userSettings/DatabaseUpdate.Properties.Settings/setting[@name='ScriptPath']")

    这不会像您基于变量命名所期望的那样返回单个 XML 节点。相反,它返回一个XPathNodeList 的实例,其基类是XmlNodeList

    您可以使用其Item() 方法按索引访问结果的各个 XML 节点:

    $node.Item(0).Value = '$(System.DefaultWorkingDirectory)/extracted/DBScripts/artefacts_Risk/'
    

    我怎么知道这个?我刚刚在控制台中输入了这个,它给了我类型名和基类:

    $node.GetType()
    

    【讨论】:

      猜你喜欢
      • 2013-02-25
      • 1970-01-01
      • 2012-03-07
      • 1970-01-01
      • 2017-01-10
      • 2013-08-23
      • 1970-01-01
      • 1970-01-01
      • 2020-07-17
      相关资源
      最近更新 更多