PDA

Показать полную графическую версию : Каким образом игнорировать и/ или удалить xmlns в заголовке xml


NickM
29-01-2025, 08:48
Уважаемые, здравствуйте!

Задался вопросом из сабжа, т.к., по какой-то причине, эти заголовки не дают корректно распарсить *.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
Примерчик бы.

NickM
29-01-2025, 09:20
В сети нашёл подсказку, что можно использовать:
local-name()
, надо попробовать, главное не запутаться, т.к. это усложняет читаемость, т.е. теперь этот простой код выглядит так:
[IO.Directory]::EnumerateFiles($PSScriptRoot,'*.xml') | foreach {
gci $_|%{([xml](gc $_.fullname)).SelectNodes('//*[local-name()="СчетаПК"]')} | ForEach-Object {$_.НомерДоговора + " " + $_.ДатаДоговора}
}


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

DJ Mogarych
29-01-2025, 09:25
А, я проглядел, что там дальше содержимое, а не только служебные заголовки.

Можно проще:

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

Sham
29-01-2025, 09:30
их добавляют (https://stackoverflow.com/a/23085544/3491376) в XmlNamespaceManager (https://learn.microsoft.com/en-us/dotnet/api/system.xml.xmlnamespacemanager.addnamespace)

YuS_2
29-01-2025, 11:07
Может кто-что дельное подскажет, т.к. Сам не понимаю, почему эти неймспейсы влияют на разбор файла. »
варианты:
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
([xml](gc source.xml -enc ([Text.Encoding]::GetEncoding('Windows-1251')))).childnodes[1]

NickM
29-01-2025, 16:33
Всем спасибо!

Решил остановиться на этом (http://forum.oszone.net/post-3035570-3.html) и приступил к написанию не эффективного кода.

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

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




© OSzone.net 2001-2012