2014-08-29 1 views
2

У меня есть конфигурационный файл .Net с узлом NLog внутри:Выберите атрибут с Xpath в XML с использованием пространства имен Powershell

<?xml version="1.0"?> 
<configuration> 
    <appSettings> 
    </appSettings> 
    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <targets async="true"> 
     <target xsi:type="File" name="f" fileName="path to file" /> 
    </targets> 
    <rules> 
     <logger name="*" minlevel="Debug" writeTo="c,f" /> 
    </rules> 
    </nlog> 
</configuration> 

Я пытаюсь изменить fileName значение, target «s с помощью Powershell.

Я использую этот код:

[xml]$xml = Get-Content $file 
$ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable) 
$ns.AddNamespace("ns", $namespace) # $namespace is `http://www.nlog-project.org/schemas/NLog.xsd` 
$values = $xml.selectNodes($xpath, $ns) 

Мое выражение XPath является //ns:nlog/ns:targets/ns:target[@ns:name='f']/@ns:fileName

Но $ значения всегда имеет 0 результаты.

Любая идея? Что я делаю не так ?

Спасибо!

ответ

3

В документе XML, есть пространство имен по умолчанию :

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"> 

Потомок элементы затем неявно приставкой с этим пространством имен. Однако, attributes do not take on a default namespace. Другими словами, атрибут в вашем входном XML равен не под названием ns:fileName, но только fileName. То же самое относится к атрибуту name.

//ns:nlog/ns:targets/ns:target[@name='f']/@fileName 

В зависимости от структуры вашего XML (и его предсказуемости) вы можете сократить выражение

//ns:target[@name='f']/@fileName 

Для того, чтобы intial выражение XPath работы, входной XML будет иметь на вид:

<targets xmlns:ns="http://www.nlog-project.org/schemas/NLog.xsd" async="true"> 
    <target xsi:type="File" ns:name="f" ns:fileName="path to file" /> 
</targets> 
Смежные вопросы