2016-04-05 1 views
0

Я провел обширные исследования в течение последних нескольких часов здесь, в блогах и в Интернете в целом. Однако ничего, что я пробовал, работает до сих пор для меня. Что у меня есть файл XML генерируется со следующим пространством имен:Игнорировать пространство имен в XPath, так как это может быть динамическим

<DeploymentReport xmlns="http://schemas.microsoft.com/sqlserver/dac/DeployReport/2012/02"> 

Я не имею никакого контроля над процессом формирования этого файла. Насколько я понимаю, его общей проблемой для XPath не работать с пространствами имен, если они не зарегистрированы или не удалены. Я бы предпочел не вносить каких-либо изменений в документ xml, и, возможно, было бы лучше как-то заставить его игнорировать его.

Я попытался с помощью /name()= и я попытался с помощью local-name в моем Xpath запросе (базовая версия которого):

//Operations/Operation/Item[@Type!='SqlIndex' and not(contains(@Value, 'Export'))] 

Однако ни один из этих методов не работал. Возможно, это потому, что я использую версию Powershell версии 3, если это имеет значение?

Причина, по которой I не нужна, чтобы зарегистрировать пространство имен, связано с тем, что его привязана к версии Sql, локально установленной (файл будет сгенерирован с этой версией). Это будет означать, что это вызовет проблему с любой другой версией. Я не хочу регистрировать их много и догадываться, какие из них они смогут разместить в будущем.

Я был бы признателен, если бы кто-нибудь мог предложить хороший способ справиться с этой ситуацией? Или у меня нет надежды, но чтобы зарегистрировать пространство имен и сохранить его в курсе каждой версии Sql?

+0

Как вы использовали 'local-name()'? – har07

+0

Да, я думаю, глядя на ответ, теперь я понимаю, что у меня была опечатка: // * [local-name() = 'Operations']/* [local-name() = 'Operation']/* [local-name () = 'Item [@type!= 'SqlIndex' и не (содержит (@Value, 'Export'))] ' –

ответ

0

Использование local-name() должны уже обработанное (обернутые для удобства чтения):

//*[local-name()='Operations'] 
/*[local-name()='Operation'] 
/*[local-name()='Item'][@Type!='SqlIndex' and not(contains(@Value, 'Export'))] 
+0

Спасибо! Теперь, глядя на ваш ответ, я понимаю, что у меня была опечатка * face palm *: // * [local-name() = 'Operations']/* [local-name() = 'Operation']/* [local-name() = 'Item [@Type! =' SqlIndex 'и не (содержит (@Value,' Export '))]' Так раздражает, когда вы попадаете на мелочи)) –

0

Это не правда, что XPath не работает с пространствами имен. Это просто не очень удобно, вот и все.

Если вам удастся определить префикс пространства имен, как

xmlns:s="http://schemas.microsoft.com/sqlserver/dac/DeployReport/2012/02" 

, то это довольно легко решить ваши Xml элементы. Ваше выражение XPath бы тогда:

//s:Operations/s:Operation/s:Item[@Type!='SqlIndex' and not(contains(@Value, 'Export'))] 

Если это невозможно объявить префикс пространства имен в вашем контексте, то вы в беде.

Полное выражение будет затем (обернутые для удобства чтения):

//*[local-name()='Operations'][namespace-uri()='http://schemas.microsoft.com/sqlserver/dac/DeployReport/2012/02'] 
/*[local-name()='Operation'][namespace-uri()='http://schemas.microsoft.com/sqlserver/dac/DeployReport/2012/02'] 
/*[local-name()='Item'][namespace-uri()='http://schemas.microsoft.com/sqlserver/dac/DeployReport/2012/02'] 
    [@Type!='SqlIndex' and not(contains(@Value, 'Export'))] 

Конечно, это все равно будет работать, если опустить [namespace-uri()='http://schemas.microsoft.com/sqlserver/dac/DeployReport/2012/02'], но тогда вы можете случайно также обратиться элементы с тем же именем в другой пространство имен, если они есть в вашем документе Xml.

В более поздних версиях XPath, вы можете также использовать

//*:Operations/*:Operation/*:Item[@Type!='SqlIndex' and not(contains(@Value, 'Export'))] 

игнорировать пространство имен.

+0

Спасибо за ваш ответ, вы упустили этот факт из моего сообщения, что я не могу контролировать, как и какой XML создается в файле, так как это происходит с помощью стороннего программного обеспечения. –

+0

В зависимости от вашего контекста может не потребоваться объявить префикс пространства имен с использованием источника Xml. –