Имею следующее:

$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
2
Carl Lam 14 Апр 2020 в 15:56

1 ответ

Лучший ответ

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

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

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

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

Чтобы получить желаемый результат:

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

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

  • Затем вы можете экспортировать объединенные элементы в файл 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 
3
mklement0 16 Апр 2020 в 20:07