问题
我正在尝试将位置的 XML 列表转换为一组对象。
XML 文件的每个位置都有一个 Location 元素。XML 属性包含对象属性值。
我希望某些目标属性具有与源属性不同的名称。
稍后我想将对象序列化为 CSV 文件,因此属性的顺序很重要。
以下是说明问题的两个位置的示例:
[xml] $InputXml = @'
<?xml version="1.0" encoding="UTF-8"?>
<CTLocations xmlns="http://www.cartrawler.com/">
<Country code="AL" name="Albania" continent="Europe">
<Location Id="7188" Name="Tirana Airport" Lat="41.42108838" Lng="19.71271276" CountryCode="AL" Address="Tirana Airport Muhamet Gjollesha Str., Muhamet Gjollesha Str., Tirana" CityName="Tirana" Airport="1" AirportCode="TIA" RailwayStation="0"/>
<Location Id="30768" Name="Tirana Downtown" Lat="41.332" Lng="19.832" CountryCode="AL" Address="Rruga E Durresit. Nr 61, Tirana" CityName="Tirana" Airport="0" RailwayStation="0"/>
</Country>
</CTLocations>
'@
部分解决方案
我的解决方案适用于具有完整属性集的元素,但在缺少任何属性时会失败。
我使用Select-Xml cmdlet 来选择重要元素,并使用PSCustomObject创建一个具有有序、重命名属性的对象。
Select-Xml -Xml $InputXml -XPath '//ns:Location' -Namespace @{ns = 'http://www.cartrawler.com/'} |
% {
$n = $_.Node
[PSCustomObject] @{
LocationCode = $n.Id
LocationName = $n.Name
Latitude = $n.Lat
Longitude = $n.Lng
CountryCode = $n.CountryCode
FormattedAddress = $n.Address
CityName = $n.CityName
ServesAirport = $n.Airport
AirportCode = $n.AirportCode
ServesRailwayStation = $n.RailwayStation
}
}
严格模式结果
当我设置了严格模式时:
Set-StrictMode -Version 3.0
第一个元素包含所有属性,因此被转换为对象:
LocationCode : 7188
LocationName : Tirana Airport
Latitude : 41.42108838
Longitude : 19.71271276
CountryCode : AL
FormattedAddress : Tirana Airport Muhamet Gjollesha Str., Muhamet Gjollesha Str., Tirana
CityName : Tirana
ServesAirport : 1
AirportCode : TIA
ServesRailwayStation : 0
第二个元素缺少 AirportCode 属性,因此 PowerShell 会引发异常:
Property 'AirportCode' cannot be found on this object. Make sure that it exists.
At line:16 char:3
+ [PSCustomObject] @{
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], PropertyNotFoundException
+ FullyQualifiedErrorId : PropertyNotFoundStrict
非严格模式结果
当我关闭严格模式时:
Set-StrictMode -Off
PowerShell 将这两个位置都转换为对象。缺少的属性为空:
LocationCode : 7188
LocationName : Tirana Airport
Latitude : 41.42108838
Longitude : 19.71271276
CountryCode : AL
FormattedAddress : Tirana Airport Muhamet Gjollesha Str., Muhamet Gjollesha Str., Tirana
CityName : Tirana
ServesAirport : 1
AirportCode : TIA
ServesRailwayStation : 0
LocationCode : 30768
LocationName : Tirana Downtown
Latitude : 41.332
Longitude : 19.832
CountryCode : AL
FormattedAddress : Rruga E Durresit. Nr 61, Tirana
CityName : Tirana
ServesAirport : 0
AirportCode :
ServesRailwayStation : 0
有没有更好的办法?
如果有更好的方法,我不想关闭严格模式来完成这项工作。
任何在严格模式下工作的东西都是可以接受的。我一直在寻找诸如T-SQL CASE 表达式或Python 的 dict get 方法之类的东西。也许还有一种 XPath 方法可以做到这一点。