|
v7: Как выбрать узел XML по неполному имени (без пространства имен)? | ☑ | ||
---|---|---|---|---|
0
antgenp
25.08.16
✎
14:45
|
Добрый день!
Есть задача - считывание xml-файлика. Она была реализована через анализатор XML v7plus.dll. Но, как оказалось, сервер пропускает и обрабатывает ответы с различными пространствами имен в файлах XML. Т.е. пространство имён может быть пустым, может быть "ns:", может быть "ns6", - и это только то, что реально попадается. Соответственно, реализация, где узел выбирался по каноническому имени (КорневойЭлемент.ВыбратьУзел("ns:НужныйУзел")) сработает только при полном совпадении и имени узла, и пространства имен. Условие метода "ВыбратьУзел" пишется, как я понял, на XSLT(?), должно быть составлено в соответствии со стандартами XPATH. Поискал в интернете варианты, как это можно сделать - под саму 1с 7.7 не нашел реализаций, но нашел, например, в описании XPATH функцию local-name(), которая возвращает имя узла без наименования пространства имен, т.е., казалось бы, как раз то, что нужно. Но, увы, никак не пойму, можно ли в условии выбора для метода 1с 7.7 "ВыбратьУзел" использовать предикат (условие). У меня, по крайней мере, не получилось. Пробовал, например, следующий вариант: ВыбратьУзел("./*[local-name()='НужныйУзел']") 1С выдает ошибку: Ошибка исполнения метода. У меня вообще не получилось ни одну функцию XPATH засунуть в условие метода - всегда получал ошибку. Может быть, я что-то делаю не так, как нужно? Или есть какая-то другая возможность сделать потребное? Или нужно идти через объявление пространства имен? У меня пока остался единственный вариант - прописать все варианты через оператор логического или "|" : ВыбратьУзел("ns:НужныйУзел|ns6:НужныйУзел|НужныйУзел") Но со временем могут добавиться новые пространства имен, а каждый раз отслеживать и своевременно их добавлять проблемно. Можете помочь решить как-то проблему? |
|||
1
antgenp
25.08.16
✎
14:57
|
Делается это для ЕГАИС, проблемы обнаружилась в актах от клиентов.
Примеры файликов: <ns:Documents xmlns:ns="http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01"> <ns:Owner> <ns:FSRAR_ID>020000231871</ns:FSRAR_ID> </ns:Owner> <ns:Document> <WayBillAct xmlns="http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01"> <Identity xmlns="http://fsrar.ru/WEGAIS/ActTTNSingle">1</Identity> <Header xmlns="http://fsrar.ru/WEGAIS/ActTTNSingle"> <IsAccept>Accepted</IsAccept> <ACTNUMBER>714d5482-ecc8-4885-8e6b-64e2472664cf</ACTNUMBER> <ActDate>2016-02-08</ActDate> <WBRegId>TTN-0005560863</WBRegId> </Header> <Content xmlns="http://fsrar.ru/WEGAIS/ActTTNSingle"/> </WayBillAct> </ns:Document> </ns:Documents> <ns:Documents xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns="http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01" xmlns:oref="http://fsrar.ru/WEGAIS/ClientRef" xmlns:pref="http://fsrar.ru/WEGAIS/ProductRef" xmlns:wa="http://fsrar.ru/WEGAIS/ActTTNSingle" Version="1.0"> <ns:Owner> <ns:FSRAR_ID>030000159487</ns:FSRAR_ID> </ns:Owner> <ns:Document> <ns:WayBillAct> <wa:Header> <wa:IsAccept>Accepted</wa:IsAccept> <wa:ACTNUMBER>МИ00000801</wa:ACTNUMBER> <wa:ActDate>2016-01-26</wa:ActDate> <wa:WBRegId>TTN-0003442235</wa:WBRegId> <wa:Note>Note</wa:Note> </wa:Header> <wa:Content></wa:Content> </ns:WayBillAct> </ns:Document> </ns:Documents> <Documents xmlns="http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01" xmlns:ns2="http://fsrar.ru/WEGAIS/TTNSingle" xmlns:ns3="http://fsrar.ru/WEGAIS/ClientRef" xmlns:ns4="http://fsrar.ru/WEGAIS/ProductRef" xmlns:ns5="http://fsrar.ru/WEGAIS/Ticket" xmlns:ns6="http://fsrar.ru/WEGAIS/ActTTNSingle" xmlns:ns7="http://fsrar.ru/WEGAIS/ConfirmTicket" xmlns:ns8="http://fsrar.ru/WEGAIS/TTNInformBReg" xmlns:ns9="http://fsrar.ru/WEGAIS/ActInventorySingle" xmlns:ns10="http://fsrar.ru/WEGAIS/ActInventoryABInfo" xmlns:ns11="http://fsrar.ru/WEGAIS/ActChargeOn" xmlns:ns12="http://fsrar.ru/WEGAIS/ActInventoryInformBReg" xmlns:ns13="http://fsrar.ru/WEGAIS/QueryParameters" xmlns:ns14="http://fsrar.ru/WEGAIS/QueryFormAB" xmlns:ns15="http://fsrar.ru/WEGAIS/ReplySSP" xmlns:ns16="http://fsrar.ru/WEGAIS/ReplySpirit" xmlns:ns17="http://fsrar.ru/WEGAIS/ReplyClient" xmlns:ns18="http://fsrar.ru/WEGAIS/ReplyAP" xmlns:ns19="http://fsrar.ru/WEGAIS/ReplyRests" xmlns:ns20="http://fsrar.ru/WEGAIS/ReplyFormA" xmlns:ns21="http://fsrar.ru/WEGAIS/ReplyFormB" xmlns:ns22="http://fsrar.ru/WEGAIS/ActWriteOff"> <Owner> <FSRAR_ID>030000033639</FSRAR_ID> </Owner> <Document> <WayBillAct> <ns6:Header> <ns6:IsAccept>Accepted</ns6:IsAccept> <ns6:ACTNUMBER>A-МИ00001743</ns6:ACTNUMBER> <ns6:ActDate>2016-02-10</ns6:ActDate> <ns6:WBRegId>TTN-0006564090</ns6:WBRegId> <ns6:Note/> </ns6:Header> <ns6:Content/> </WayBillAct> </Document> </Documents> |
|||
2
antgenp
25.08.16
✎
16:39
|
АП
Приношу свои извинения за форматирование примеров - если подскажите, как пост можно отредактировать, исправлюсь. Ещё раз вкратце проблема: Приходят XML с одними и теми же собственными именами узлов, но разными пространствами имен. В остальном всё то же самое. Пример: <Header></Header> <ns:Header></ns:Header> <ns6:Header><ns6:Header> Могу я с помощью метода ВыбратьУзел() v7plus.dll в 1с 7.7 выбрать узел с наименованием Header без оглядки на пространство имен? Или в какую сторону идти курить мануалы? |
|||
3
Djelf
25.08.16
✎
16:50
|
(0) Можно убрать все пространства имен и работать без них.
|
|||
4
antgenp
25.08.16
✎
16:58
|
Спасибо, сегодня попробую.
|
|||
5
antgenp
26.08.16
✎
09:07
|
Не выходит.
Выдает ошибку: msxml3.dll: Ключевое слово "xsl:stylesheet" не может содержать узлы "PCDATA". |
|||
6
antgenp
26.08.16
✎
11:47
|
Погуглил, нашел немного другой вариант:
Функция хмлУдалитьПространстваИмен(хмлСообщение) //:MSXML2.DOMDocument xslDoc=СоздатьОбъект("MSXML2.DOMDocument"); xslDoc.async = 0; xslDoc.loadXML(" |<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform""> |<xsl:output method=""xml""/> |<xsl:template match=""/""> |<xsl:copy> |<xsl:apply-templates /> |</xsl:copy> |</xsl:template> |<xsl:template match=""*""> |<xsl:element name=""{local-name()}""> |<xsl:apply-templates select=""@* | node()"" /> |</xsl:element> |</xsl:template> |<xsl:template match=""@*""> |<xsl:attribute name=""{local-name()}""><xsl:value-of select=""."" |/></xsl:attribute> |</xsl:template> |<xsl:template match=""text() | processing-instruction() | comment()""> |<xsl:copy /> |</xsl:template> |</xsl:stylesheet> |"); xmlDoc=СоздатьОбъект("MSXML2.DOMDocument"); хмлСообщение.transformNodeToObject(xslDoc, xmlDoc); Возврат xmlDoc; КонецФункции Сейчас тестирую, пока похоже, что работает так, как мне надо. Но, т.к. XSLT не знаю, то пока не уверен в этом ) Спасибо за помощь. |
|||
7
Djelf
26.08.16
✎
12:42
|
(5) Ну я тоже не сам это преобразование придумал.
Странно... это выдернуто из рабочего модуля егаис, хотя для такой ошибки достаточно того чтобы одна буковка не так скопировалась. |
|||
8
antgenp
26.08.16
✎
15:14
|
А рабочий модуль для семерки или для восьмерки?
У меня ещё были проблемы с любыми упоминаниями кодировки. Ошибка была что-то вроде "Недопустимая кодировка" или как-то так,при чем пробовал менять указанную кодировку, ставил вариант с кодировкой из вашего примера, но ошибка всё равно сохранялась. Пришлось убрать все упоминания о кодировке. А может быть это из-за различных версий платформы 1с? |
|||
9
Djelf
26.08.16
✎
15:24
|
(8) Ну раз в коде СоздатьОбъект то 7ка.
Ты случаем в функцию не текст передашь? Туда MSXML2.DOMDocument передавать надо. |
|||
10
antgenp
26.08.16
✎
16:09
|
Нет, не текст, но и не MSXML2.DOMDocument, а объект, загруженный с помощью анализатора XML v7plus.dll.
У меня всё было под него написано, поэтому, возможно, и не сработал твой пример. С другой стороны, тот вариант, который я тебе написал, вроде работает и таким образом. Получается, что у меня сейчас создается объект анализатора XML, потом я его передаю в функцию, функция возвращает элемент MSXML2.DOMDocument, продолжать работу с ним анализатор не может, поэтому его приходится снова открывать анализатором, благо в параметр анализатора можно как писать имя файла на диске, так и объект. Выглядит это так: ПарсерХМЛ = СоздатьОбъект("AddIn.XMLParser"); ХМЛ = ПарсерХМЛ.СоздатьДокумент(); ХМЛ.Загрузить(ФайлОтвета); xmlWithoutNamespaces= хмлУдалитьПространстваИмен(ХМЛ); ... ХМЛ.Загрузить(xmlWithoutNamespaces); Если можно сделать лучше или это дикая ересь, то подскажи как исправить, пожалуйста. Просто изначально всё было написано под анализатор, а таким образом получилось сделать с минимумом изменений. |
|||
11
antgenp
26.08.16
✎
16:21
|
Если я правильно понимаю, анализатор XML v7plus.dll тоже работает через MSXML, но может не совпадать версия - сейчас глянул какие версии используются - ВерсияАнализатора 2.0, ВерсияБазовогоАнализатора 3.0.
Из этого мне не совсем понятно, MSXML2 или MSXML3 используется компонентой v7plus.dll, может быть проблема была в том, что всё-таки используется версия 3.0 а я её передавал в функцию для обработки 2-й версией. Соответственно, возникали ошибки из-за какого-то различия в понимании синтаксиса. |
|||
12
trad
29.08.16
✎
09:51
|
(0) не нужно делать никакой обработки xml, ни выпиливание ns, ни xslt-преобразований, ни поиска по подстроке.
Нужно просто обучить свой DOMDocument. Сказать ему под каким псевдонимом ты ожидаешь увидеть каждый URI В твоем случае делается это так: ХМЛ=СоздатьОбъект("Msxml2.DOMDocument"); ХМЛ.setProperty("SelectionNamespaces", "xmlns:wa='http://fsrar.ru/WEGAIS/ActTTNSingle'"); И далее везде в коде работаешь через упомянутый wa Номер = ДокXML.selectSingleNode("//wa:ACTNUMBER").text; |
|||
13
trad
29.08.16
✎
09:53
|
А в целом, для работы с УТМ ЕГАИС у меня есть такая функция, где перечислены все используемые в УТМ URI и их типовые псевдонимы:
Функция СоздатьДокументОбменаУТМ() ПространстваИменУТМ = " |xmlns:ns='http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01' |xmlns:c='http://fsrar.ru/WEGAIS/Common' |xmlns:ce='http://fsrar.ru/WEGAIS/CommonEnum' |xmlns:oref='http://fsrar.ru/WEGAIS/ClientRef' |xmlns:pref='http://fsrar.ru/WEGAIS/ProductRef' |xmlns:wb='http://fsrar.ru/WEGAIS/TTNSingle' |xmlns:tc='http://fsrar.ru/WEGAIS/Ticket' |xmlns:wa='http://fsrar.ru/WEGAIS/ActTTNSingle' |xmlns:ctc='http://fsrar.ru/WEGAIS/ConfirmTicket' |xmlns:ain='http://fsrar.ru/WEGAIS/ActInventorySingle' |xmlns:ainp='http://fsrar.ru/WEGAIS/ActChargeOn' |xmlns:qp='http://fsrar.ru/WEGAIS/QueryParameters' |xmlns:wbr='http://fsrar.ru/WEGAIS/TTNInformBReg' |xmlns:aint='http://fsrar.ru/WEGAIS/ActInventoryInformBReg' |xmlns:qf='http://fsrar.ru/WEGAIS/QueryFormAB' |xmlns:awr='http://fsrar.ru/WEGAIS/ActWriteOff' |xmlns:rpp='http://fsrar.ru/WEGAIS/RepProducedProduct' |xmlns:rpi='http://fsrar.ru/WEGAIS/RepImportedProduct' | |xmlns:rssp='http://fsrar.ru/WEGAIS/ReplySSP' |xmlns:rs='http://fsrar.ru/WEGAIS/ReplySpirit' |xmlns:rc='http://fsrar.ru/WEGAIS/ReplyClient' |xmlns:rap='http://fsrar.ru/WEGAIS/ReplyAP' |xmlns:rst='http://fsrar.ru/WEGAIS/ReplyRests' |xmlns:rfa='http://fsrar.ru/WEGAIS/ReplyFormA' |xmlns:rfb='http://fsrar.ru/WEGAIS/ReplyFormB' | |xmlns:rfhb='http://fsrar.ru/WEGAIS/ReplyHistFormB' |xmlns:orefv='http://fsrar.ru/WEGAIS/ReplyClientVersion' | |xmlns:oref2='http://fsrar.ru/WEGAIS/ClientRef_v2' |xmlns:pref2='http://fsrar.ru/WEGAIS/ProductRef_v2' |xmlns:qrrp='http://fsrar.ru/WEGAIS/QueryRejectRepProduced' |xmlns:qrri='http://fsrar.ru/WEGAIS/QueryRejectRepImported' | |xmlns:rssp2='http://fsrar.ru/WEGAIS/ReplySSP_v2' |xmlns:rs2='http://fsrar.ru/WEGAIS/ReplySpirit_v2' |xmlns:rc2='http://fsrar.ru/WEGAIS/ReplyClient_v2' |xmlns:rap2='http://fsrar.ru/WEGAIS/ReplyAP_v2' |xmlns:rst2='http://fsrar.ru/WEGAIS/ReplyRests_v2' |xmlns:rfa2='http://fsrar.ru/WEGAIS/ReplyForm1' |xmlns:rfb2='http://fsrar.ru/WEGAIS/ReplyForm2' |xmlns:rfhb2='http://fsrar.ru/WEGAIS/ReplyHistForm2' |xmlns:wb2='http://fsrar.ru/WEGAIS/TTNSingle_v2' |xmlns:wa2='http://fsrar.ru/WEGAIS/ActTTNSingle_v2' |xmlns:ainp2='http://fsrar.ru/WEGAIS/ActChargeOn_v2' |xmlns:wbr2='http://fsrar.ru/WEGAIS/TTNInformF2Reg' |xmlns:aint2='http://fsrar.ru/WEGAIS/ActInventoryInformF2Reg' |xmlns:qf2='http://fsrar.ru/WEGAIS/QueryFormF1F2' |xmlns:awr2='http://fsrar.ru/WEGAIS/ActWriteOff_v2' |xmlns:tfs='http://fsrar.ru/WEGAIS/TransferFromShop' |xmlns:tts='http://fsrar.ru/WEGAIS/TransferToShop' |xmlns:ripf1='http://fsrar.ru/WEGAIS/RepInformF1Reg' |xmlns:nattn='http://fsrar.ru/WEGAIS/ReplyNoAnswerTTN' |xmlns:rsts2='http://fsrar.ru/WEGAIS/ReplyRestsShop_v2' |xmlns:asiu='http://fsrar.ru/WEGAIS/Asiiu' |xmlns:asiut='http://fsrar.ru/WEGAIS/AsiiuTime' | |xmlns:ains2='http://fsrar.ru/WEGAIS/ActChargeOnShop_v2' |xmlns:awrs2='http://fsrar.ru/WEGAIS/ActWriteOffShop_v2' |xmlns:wbfu='http://fsrar.ru/WEGAIS/InfoVersionTTN' |xmlns:qbc='http://fsrar.ru/WEGAIS/QueryBarcode' |xmlns:rbc='http://fsrar.ru/WEGAIS/ReplyBarcode' |xmlns:rrwb='http://fsrar.ru/WEGAIS/RequestRepealWB' |xmlns:crwb='http://fsrar.ru/WEGAIS/ConfirmRepealWB' |xmlns:rraco='http://fsrar.ru/WEGAIS/RequestRepealACO' |xmlns:rrawo='http://fsrar.ru/WEGAIS/RequestRepealAWO' |"; ДокXML = СоздатьОбъект("Msxml2.DOMDocument"); ДокXML.setProperty("SelectionNamespaces", ПространстваИменУТМ); Возврат ДокXML; КонецФункции |
|||
14
trad
29.08.16
✎
09:55
|
получить актуальный список пространств имен можно в УТМ, в документе WB_DOC_SINGLE_01.xsd
|
|||
15
sapphire
29.08.16
✎
13:41
|
(0) Используйте Microsoft DOM Document.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |