Выберите один узел из XML с помощью Powershell - PullRequest
1 голос
/ 05 августа 2020

Я изо всех сил пытаюсь прочитать XML:

<?xml version="1.0" encoding="utf-8"?>
        <tmx version="1.4">
          <header creationtool="B&amp;R Automation Studio" creationtoolversion="4.2" datatype="unknown" segtype="sentence" adminlang="en" srclang="en" o-tmf="TMX">
            <note>Change the namespace to define where this text module should be located within the logical structure of your texts</note>
            <prop type="x-BR-TS:Namespace">ZagVision</prop>
          </header>
          <body>
            <tu tuid="BcrWenglor.Init">
              <tuv xml:lang="en">
                <seg>Not initialized. </seg>
              </tuv>
              <tuv xml:lang="de">
                <seg>Nicht initialisiert. </seg>
              </tuv>
            </tu>
            <tu tuid="BcrUsbHid.WarnScanner">
              <tuv xml:lang="fr">
                <seg>BcrUsbHid : Avertissement général Scanner, scanner non reconnu ou interface défectueuse. </seg>
              </tuv>
              <tuv xml:lang="en">
                <seg>BcrUsbHid: General warning Scanner, scanner not recognized or interface faulty. </seg>
              </tuv>
              <tuv xml:lang="de">
                <seg>BcrUsbHid: Allgemeine Warnung Scanner, Scanner wurde nicht erkannt oder Schnittstelle fehlerhaft. </seg>
              </tuv>
            </tu>
      </body>
    </tmx>

Я попытался получить доступ к одному узлу с помощью XPath с помощью "SelectSingleNode", как описано здесь: Синтаксис XPath

$Path = "C:\Temp\ZagVision.tmx"

$result = Get-ChildItem -Path $Path -Filter '*.tmx'  -Recurse | 
    ForEach-Object {
        [xml]$xml = Get-Content -Path $_.FullName
        foreach ($node in $xml.tmx.body.tu) {
            [PSCustomObject]@{
              'FileName'          = $_.BaseName
              'NameSpace'         = $node.ParentNode.ParentNode.header.prop.'#text'
              'LastChangeFile'    = $_.LastWriteTime
              'TextId'            = $node.tuid
              
              'fr'         = $node.SelectSingleNode("//tuv[@lang='fr']") 
              'en'         = $node.ChildNodes[1].seg # works fine , but only if we have 3 nodes
              'de'         = $node.ChildNodes[2].seg
          
            }                
        }
 }
 $result

Вывод:

FileName       : ZagVision
NameSpace      : ZagVision
LastChangeFile : 16.07.2020 08:41:38
TextId         : BcrUsbHid.WarnScanner
fr             : 
en             : BcrUsbHid: General warning Scanner, scanner not recognized or 
                 interface faulty. 
de             : BcrUsbHid: Allgemeine Warnung Scanner, Scanner wurde nicht 
                 erkannt oder Schnittstelle fehlerhaft. 

Поскольку я только начал работать с PowerShell, вероятно, это что-то очень базовое c Я здесь делаю не так ... Спасибо заранее.

Ответы [ 2 ]

0 голосов
/ 06 августа 2020

@ Uuuuuumm Да, спасибо! Зарегистрируйте пространство имен и измените выражения пути с

$node.SelectSingleNode("//tuv[@xml:lang='fr']", $ns).seg 

на

$node.SelectSingleNode("tuv[@xml:lang='fr']", $ns).seg 

сделал это.

Вот рабочий код:

#$Path = "C:\Temp\ZagVision.tmx"

$result = Get-ChildItem -Path $Path -Filter '*.tmx'  -Recurse | 
    ForEach-Object {
        [xml]$xml = Get-Content -Path $_.FullName

        $ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
        $ns.AddNamespace("xml", "http://www.w3.org/XML/1998/namespace")

        foreach ($node in $xml.tmx.body.tu) {
            [PSCustomObject]@{
              'FileName'          = $_.BaseName
              'NameSpace'         = $node.ParentNode.ParentNode.header.prop.'#text'
              'LastChangeFile'    = $_.LastWriteTime
              'TextId'            = $node.tuid
              
              'fr'         = $node.SelectSingleNode("tuv[@xml:lang='fr']", $ns).seg
              'en'         = $node.SelectSingleNode("tuv[@xml:lang='en']", $ns).seg
              'de'         = $node.SelectSingleNode("tuv[@xml:lang='de']", $ns).seg
          
            }                
        }
 }
 #$result
$result | Export-Csv -NoTypeInformation "C:\Temp\Messages.csv" -Encoding Default  -Delimiter ';' #-Append
Invoke-Item "C:\Temp\Messages.csv"
0 голосов
/ 05 августа 2020

Вам нужно было зарегистрировать пространство имен xml, чтобы использовать атрибут xml: lang с selectSingleNode:


$result = Get-ChildItem -Path $Path -Filter '*.tmx'  -Recurse | 
    ForEach-Object {
        [xml]$xml = Get-Content -Path $_.FullName
        
        $ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable) # added this line
        $ns.AddNamespace("xml", "http://www.w3.org/XML/1998/namespace") # added this line
        
        foreach ($node in $xml.tmx.body.tu) {
            [PSCustomObject]@{
              'FileName'          = $_.BaseName
              'NameSpace'         = $node.ParentNode.ParentNode.header.prop.'#text'
              'LastChangeFile'    = $_.LastWriteTime
              'TextId'            = $node.tuid
              
              'fr'         = $node.SelectSingleNode("//tuv[@xml:lang='fr']", $ns).seg # modified this line
              'en'         = $node.ChildNodes[1].seg # works if we have 3 nodes
              'de'         = $node.ChildNodes[2].seg
          
            }                
        }
 }
 $result

Я понял это из ошибки, возникшей при попытке сделать это: "//tuv[@xml:lang='fr']"

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