Не удается загрузить документ XML с помощью PowerShell - PullRequest
0 голосов
/ 05 января 2010

Почему-то я не могу прочитать XML-файл с очень простой структурой в моем скрипте PowerShell. XML-файл создается с помощью «Microsoft Log Parser Toolkit», и я хочу загрузить его содержимое в базу данных.

Сценарий очень прост:

$datalist=[xml] (gc ".\users.xml");
foreach ($ROW in $datalist.ROOT.ROW) {
        Write-host $ROW.CompName;
}

Ожидаемый вывод

User1
User2

но ничего не распечатывается. Я видел похожие примеры работы (например, здесь , где они используют PowerShell для анализа выходных данных stsadm -o enumsites.

Что мне здесь не хватает?

Содержимое файла users.xml тоже просто:

<?xml version="1.0" encoding="ISO-10646-UCS-2" standalone="yes" ?>
<!DOCTYPE ROOT[
 <!ATTLIST ROOT DATE_CREATED CDATA #REQUIRED>
 <!ATTLIST ROOT CREATED_BY CDATA #REQUIRED>
 <!ELEMENT CompName (#PCDATA)>
 <!ELEMENT SoftwareName (#PCDATA)>
 <!ELEMENT ROW (CompName, SoftwareName)>
 <!ELEMENT ROOT (ROW*)>
]>
<ROOT DATE_CREATED="2009-12-30 10:44:23" CREATED_BY="Microsoft Log Parser V2.2">
 <ROW>
  <CompName>User1</CompName>
  <SoftwareName>Adobe Reader 9.0</SoftwareName>
 </ROW>
 <ROW>
  <CompName>User2</CompName>
  <SoftwareName>CorelDraw Graphics Suite X4</SoftwareName>
 </ROW>
</ROOT>

Ответы [ 2 ]

3 голосов
/ 05 января 2010

Это должно решить:

Select-Xml -Xml $datalist -XPath '//ROW' | % { $_.Node.CompName }

Редактировать: в соответствии с MediaAndMicrocode Where-Object должен использоваться для фильтрации недопустимых значений, но в этом случае он работает без него.


В чем проблема?

Что интересно:

poshdev >[62]: $x.ROOT | select -exp row
Select-Object : Property "row" cannot be found.
At line:1 char:17
+ $x.ROOT | select <<<<  -exp row
    + CategoryInfo          : InvalidArgument: (:PSObject) [Select-Object], PSArgumentException
    + FullyQualifiedErrorId : ExpandPropertyNotFound,Microsoft.PowerShell.Commands.SelectObjectCommand


CompName                                                                 SoftwareName
--------                                                                 ------------
User1                                                                    Adobe Reader 9.0
User2                                                                    Corel Photoshop 12

Итак, если свойство не может быть найдено, давайте проверим его членов:

$datalist.ROOT | gm

показывает, что это коллекция строк и XmlElement.Основываясь на знаниях, это работает как ожидалось:

$datalist.root[1].row

Это означает, что приведение к [xml] создало 2 элемента: строку (вероятно, из части DTD) и xml.Другой обходной путь - просто удалить часть DTD из XML.

1 голос
/ 05 января 2010

Вам не нужно удалять часть DTD с помощью Select-Xml, вы можете просто передать ее в Where-Object. Когда вы запрашиваете все узлы с помощью Select-Xml (Select-Xml // *), Select-Xml автоматически собирает все пространства имен:

Select-Xml -Xml $datalist -XPath '//*' |
    Where-Object { $_.Node.CompName } |
    Foreach-Object { $_.Node.CompName } 

Вы также должны знать, что передача файла в Select-Xml значительно быстрее, чем при использовании Get-Content для его чтения. Get-Content читает построчно, и это может очень медленно работать с большими файлами. реж | Select-Xml не будет читать файлы построчно.

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...