Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Каким образом игнорировать и/ или удалить xmlns в заголовке xml (http://forum.oszone.net/showthread.php?t=356090)

NickM 29-01-2025 08:48 3035568

Каким образом игнорировать и/ или удалить xmlns в заголовке xml
 
Уважаемые, здравствуйте!

Задался вопросом из сабжа, т.к., по какой-то причине, эти заголовки не дают корректно распарсить *.xml с помощью .SelectNodes.

Допустим, есть универсальный формат выгрузки в банк из 1с8:
Код:

<?xml version="1.0" encoding="windows-1251"?>
<СчетаПК xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://v8.1c.ru/edi/edi_stnd/109" xsi:type="СчетПК" ДатаФормирования="2025-01-29" НомерДоговора="11234567890" ДатаДоговора="2020-01-01" НаименованиеОрганизации="Муниципальное бюджетное общеобразовательное учреждение" ИНН="021001001" БИК="048073601" ИдПервичногоДокумента="8d1fbfe6-2cbd-11ef-958e-00155da20c00" НомерРеестра="5" ДатаРеестра="2024-02-05">
</СчетаПК>

Сейчас думаю, каким образом этот момент обойти, эти неймспейсы:
  • каким-то образом их игнорировать;
  • модифицировать файл и вырезать их;

Может кто-что дельное подскажет, т.к. Сам не понимаю, почему эти неймспейсы влияют на разбор файла.

Например, вот такой простенький код получения даты и № договора без удаления этих неймспейсов не выводит ничего:
Код:

[IO.Directory]::EnumerateFiles($PSScriptRoot,'*.xml') | foreach {
gci $_|%{([xml](gc $_.fullname)).SelectNodes('//СчетаПК')} | ForEach-Object {$_.НомерДоговора + " " + $_.ДатаДоговора}
}


DJ Mogarych 29-01-2025 09:20 3035569

Примерчик бы.

NickM 29-01-2025 09:20 3035570

В сети нашёл подсказку, что можно использовать:
Код:

local-name()
, надо попробовать, главное не запутаться, т.к. это усложняет читаемость, т.е. теперь этот простой код выглядит так:
Код:

[IO.Directory]::EnumerateFiles($PSScriptRoot,'*.xml') | foreach {
 gci $_|%{([xml](gc $_.fullname)).SelectNodes('//*[local-name()="СчетаПК"]')} | ForEach-Object {$_.НомерДоговора + " " + $_.ДатаДоговора}
}

Цитата:

Цитата DJ Mogarych
Примерчик бы. »

В первом сообщении приложен как пример, так и попытка чтения.

DJ Mogarych 29-01-2025 09:25 3035572

А, я проглядел, что там дальше содержимое, а не только служебные заголовки.

Можно проще:
Код:

([xml](gc C:\temp\temp.xml)).счетапк |% {"$($_.номердоговора) $($_.датадоговора)"}

Sham 29-01-2025 09:30 3035573

их добавляют в XmlNamespaceManager

YuS_2 29-01-2025 11:07 3035576

Цитата:

Цитата NickM
Может кто-что дельное подскажет, т.к. Сам не понимаю, почему эти неймспейсы влияют на разбор файла. »

варианты:
1.
Код:

$xml = [xml](gc test.xml -raw)
$xml.getelementsbytagname('СчетаПК')

2.
Код:

$xml = [xml](gc test.xml -raw)
$ns = new-object xml.xmlnamespacemanager($xml.nametable)
$ns.addnamespace('ns', $xml.documentelement.namespaceuri)
$xml.selectnodes("//ns:СчетаПК",$ns)


SQLai Lama 29-01-2025 14:48 3035581

Код:

([xml](gc source.xml -enc ([Text.Encoding]::GetEncoding('Windows-1251')))).childnodes[1]

NickM 29-01-2025 16:33 3035589

Всем спасибо!

Решил остановиться на этом и приступил к написанию не эффективного кода.

Пытаюсь обойти кривую реализацию зарплатного проекта в 1с8 в централизованной бухгалтерии, когда буду выгружать кучу-сотни реестров в универсальном *.xml-формате, а после, с помощью powershell, конвертировать их в форматы трёх и более разных банков.

Вроде что-то получается, но поделиться стесняюсь, код действительно ужасен.


Время: 07:06.

Время: 07:06.
© OSzone.net 2001-