Somehow I can’t read an XML file with very simple structure in my PowerShell script. The XML file is generated by “Microsoft Log Parser Toolkit” and I want to load its contents into a database.
The script is very simple:
$datalist=[xml] (gc ".\users.xml");
foreach ($ROW in $datalist.ROOT.ROW) {
Write-host $ROW.CompName;
}
The expected output is
User1
User2
but nothing gets printed out. I have seen similar examples working (for instance here where they use PowerShell to parse outputs of stsadm -o enumsites.
What am I missing here?
Contents of the users.xml is simple, too:
<?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>
This should solve it:
Edit: according to MediaAndMicrocode Where-Object should be used to filter out invalid values, but in this case it works without it.
Where lies the problem?
What is interesting:
So if property can not be found, let’s check its members:
it shows that is a collection of string and XmlElement. Based on the knowledge this works as expected:
It means, that cast to [xml] created 2 items: string (probably from the DTD part) and xml. Other workaround is simply remove the DTD part from the xml.