Powershell Объединение объектов, которые были подобраны с xml - PullRequest
2 голосов
/ 14 апреля 2020

У меня есть следующее:

$XPath = "//INVOICEHEADER"
$XPath2 = "//FILE"
# path where we need to look for the xml. * means all files that end in .xml
$Path = "$sourcelocation\*.xml"

# Select-Xml -Path $Path -XPath $Xpath | 
# Select-Object -EA SilentlyContinue -ExpandProperty Node |
# # export results append to the file NNUH.csv
# Export-Csv -append -Path $resultfilepathtemp -NoTypeInformation 
Get-ChildItem -Path $Path | 

ForEach-Object {
    $xml = Select-Xml -Path $_.FullName -XPath $Xpath
    $results = Select-Object -InputObject $Xml -EA SilentlyContinue -ExpandProperty Node
    # Write-Output $results
    $xml = Select-Xml -Path $_.FullName -XPath $Xpath2 
    $results2 = Select-Object -InputObject $Xml -EA SilentlyContinue -ExpandProperty Node

    # Need to join results together

    Export-Csv -InputObject $results -append -Path $resultfilepathtemp -NoTypeInformation 
}

Я пытаюсь соединить два объекта, которые я взял из. xml. Борьба за то, как получить это для вывода в файл. . xml выглядит следующим образом:

XML
<?xml version="1.0" encoding="UTF-8"?>
<INVOICEIMPORT TYPE="INVOICE">
  <INVOICES>
    <INVOICE>
      <INVOICEHEADER>
        <CATEGORY>1</CATEGORY>
        <PURCHASEORDERNO>AA00000</PURCHASEORDERNO>
        <OURREF>AA00000</OURREF>
        <ATTRIB2>Client name</ATTRIB2>
        <ATTRIB3>Address</ATTRIB3>
        <SUPPLIERREF>1000000000</SUPPLIERREF>
        <INVOICEDATE>20200302</INVOICEDATE>
        <ARRIVAL>20200401</ARRIVAL>
        <AMOUNT>100,401.20</AMOUNT>
        <VATAMOUNT>13,900.20</VATAMOUNT>
        <CURRENCY.CURRENCYID>GBP</CURRENCY.CURRENCYID>
        <CLIENT.CODE>9999</CLIENT.CODE>
        <ITVNCODE>No supplier found</ITVNCODE>
      </INVOICEHEADER>
      <FILES>
        <FILE>
          <TRANSACTIONTYPE>X104</TRANSACTIONTYPE>
          <FULLFILENAME>PP_XXXX_00001.pdf</FULLFILENAME>
          <PAGENUMBER>1</PAGENUMBER>
        </FILE>
      </FILES>
    </INVOICE>
  </INVOICES>
</INVOICEIMPORT>

, и вывод должен быть в формате, аналогичном следующему:

"CATEGORY","PURCHASEORDERNO","OURREF","ATTRIB2","ATTRIB3","SUPPLIERREF","INVOICEDATE","ARRIVAL","AMOUNT","VATAMOUNT","CURRENCY.CURRENCYID","CLIENT.CODE","ITVNCODE","TRANSACTIONTYPE","FULLTIMENAME","PAGENUMBER"
"1","AA00000","AA00000","Client name","Address","1000000000","20200302","20200401","100,401.20","13,900.20","GBP","9999","No supplier found","X104","PP_XXXX_00001.pdf","1"

Думаю, я уже близко к этому, поскольку я новичок в PowerShell (чуть более недели). У меня установлен PowerShell 5.1 на сервере, на котором в конечном итоге будет выполняться код. Я пытался присоединиться к ним:

# Need to join results together
     $endresult = $results + $results2
    Export-Csv -InputObject $endresult -append -Path $resultfilepathtemp -NoTypeInformation 

Но я получаю сообщение об ошибке:

Export-Csv : Cannot bind argument to parameter 'InputObject' because it is null.
At C:\Client\ClientX.ps1:74 char:29
+     Export-Csv -InputObject $rpc -append -Path $resultfilepathtemp -N ...
+                             ~~~~
    + CategoryInfo          : InvalidData: (:) [Export-Csv], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ExportCsvCo 
   mmand

1 Ответ

3 голосов
/ 14 апреля 2020

Ваши $results и $results2 переменные содержат (потенциально массивы ) System.Xml.XmlElement экземпляров.

  • Если переменные содержит массивы (если ваш ввод XML имеет несколько INVOICE элементов, что представляется вероятным):

    • Использование + с массивами объединяет их (создает новый массив, который содержит все элементы массива LHS, а затем все элементы массива RHS) - это не будет делать то, что вы хотите, то есть объединить дочерние элементы из , соответствующие XML elements.
  • Если переменные содержат скаляры (* экземпляр 1030 * каждая):

    • Использование + завершается с ошибкой , поскольку XmlElement не определяет перегрузку для оператора +.

Чтобы получить требуемый вывод:

  • Вы должны обработать массивы в парах элементов .

  • Для каждой пары необходимо объединить Inpu t XmlElement s для формирования элемента, который содержит union соответствующих дочерних узлов.

  • Затем вы можете экспортировать объединенные элементы в файл CSV с помощью Export-Csv.

$XPath = "//INVOICEHEADER"
$XPath2 = "//FILE"
$Path = "$sourcelocation\*.xml"

Get-ChildItem -Path $Path | 
  ForEach-Object {

    # Load and parse the XML file once.
    [xml] $xml = Get-Content -Raw $_.FullName

    # Run the XPath queries.
    $results = $xml.SelectNodes($XPath)
    $results2 = $xml.SelectNodes($XPath2)

    # Process the results in pairs:
    # Create a new element containing the union of the child elements.
    foreach ($i in 0..($results.Count-1)) {
      # Append the child nodes of the RHS array element to the LHS
      # array element.
      # NOTE: @(...) ensures that the child nodes are collected in an aux.
      #       array up front; without that, the .AppendChild() calls would
      #       interfere with the enumeration of .ChildNodes.
      foreach ($child in @($results2[$i].ChildNodes)) {
        $null = $results[$i].AppendChild($child)
      }
      # Output the merged element.
      $results[$i]
    }

  } | Export-Csv -Path $resultfilepathtemp -NoTypeInformation 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...