Jak czytać o: xml za pomocą PowerShell?
Mam następujący plik xml, ale nie wiem, jak go odczytać za pomocą programu PowerShell. Czy ktoś może pomóc? Dzięki!
Muszę uzyskać wartość adresu URL z programu PowerShell.
<o:OfficeConfig xmlns:o="urn:xxx:xxx:xxx">
<o:services>
<o:service o:name="xxxx">
<o:url>https://xxx.xxx</o:url>
</o:service>
</o:services>
</o:OfficeConfig>
Z góry dziękuję!
Odpowiedzi
Możesz skorzystać z faktu, że wygodna, oparta na właściwościach adaptacja XML DOM w PowerShell zasadniczo ignoruje przestrzenie nazw, umożliwiając po prostu drążenie w dół do interesującego elementu za pomocą niekwalifikowanych nazw elementów:
([xml] (Get-Content -Raw file.xml)).OfficeConfig.services.service.url
Natomiast XPath na bazie Select-Xmlcmdlet to przestrzenie nazw, a zatem wymaga wyraźnej obsługę przestrzeni nazw - lub obejście poprzez local-name()funkcję, jak pokazano w odpowiedzi Mathias R. Jessen jest .
Jeśli chcesz używać właściwej obsługi przestrzeni nazw - która ostatecznie jest bardziej niezawodna, ale nie zawsze jest konieczna - użyj następujących poleceń:
(
Select-Xml '//o:url' file.xml -Namespace @{ o='urn:schemas-microsoft-com:office:office' }
).Node.InnerText
Zwróć uwagę na potrzebę przekazania tablicy hashtable (
@{ ... }), która deklaruje używane prefiksy przestrzeni nazw i adresy URL, co jest warunkiem wstępnym, aby móc używać prefiksów (o:w tym przypadku) w zapytaniu XPath.- Nazwy przedrostków nie muszą odpowiadać nazwom w oryginale, o ile są zgodne z
-Namespaceargumentem i są mapowane na oryginalne adresy URL.
- Nazwy przedrostków nie muszą odpowiadać nazwom w oryginale, o ile są zgodne z
Select-Xmlzwraca obiekty opakowujące wokół dopasowanych System.Xml.XmlNodeinstancji, więc.Nodejest wymagany, aby uzyskać dostęp do tych ostatnich, a.InnerTextnastępnie zwraca zawartość tekstową węzła.- Na marginesie: ta potrzeba dostępu
.Nodejest niewygodna, ponieważ typowym przypadkiem użycia jest dbanie oXmlNodejedyną; Sugestia GitHub nr 13669 ma na celu złagodzenie bólu za pomocą
-Rawprzełącznika, który zwracaXmlNodebezpośrednio instancje.
- Na marginesie: ta potrzeba dostępu
Możesz użyć Select-Xml:
$rawXml = @' <o:OfficeConfig xmlns:o="urn:schemas-microsoft-com:office:office"> <o:services> <o:service o:name="GetFederationProvider"> <o:url>https://odc.officeapps.live.com/odc/emailhrd/getfederationprovider</o:url> </o:service> </o:services> </o:OfficeConfig> '@ $urlNode = $rawXml |Select-Xml -XPath '//*[local-name() = "url"]' |Select -Expand Node $url = $urlNode.innerText
$url będzie teraz zawierać ciąg "https://odc.officeapps.live.com/odc/emailhrd/getfederationprovider"
Ponieważ zwracasz json, możesz po prostu przekonwertować z json na obiekt PowerShell:
$configServiceUrl = "https://officeclient.microsoft.com/config16processed?rs=en-us&build=16.0.7612" $headers = @{'Accept' = 'application/json'}
$getFederationProviderEndpoint = Invoke-WebRequest -Uri "$($configServiceUrl)&services=GetFederationProvider" -Headers $headers -Method GET
$obj = $getFederationProviderEndpoint.Content | ConvertFrom-Json
$obj.'o:officeconfig'.'o:services'.'o:service'.'o:url'