Форум » [x]Harbour » Формирование XML » Ответить

Формирование XML

Sergy: Добрый день Почему-то уверен, что "где-то" есть простая и удобная функция формирования xml файла из, допустим, хэша. Ооочень не хочу изобретать велосипед. Поиск по hb_Xml вывел на парсер, а мне нужно наоборот. Спасибо.

Ответов - 6

SergKis: Sergy пишет Ооочень не хочу изобретать велосипед. У меня вышло так - храню xml шаблон для клиентов, как базу, прописан с мах возможной структурой, где в тэгах стоят типа макросы\ключи из ini или hash, т.е. "<...>-^001</...>"+CRLF ... // - означает, что тэг не обязательный - читаю такой шаблон и из (ini\hash) источника заменяю ключи ^001 на данные, если есть, если нет и есть -, то тэг на выход не идет, если тэг обязательный, а ключа нет, убираю его, в смысле ключ, получая <...></...> - замену можно делать как StrTran на строку шаблона, либо построчно hb_Atokens(cBuf, CRLF). Где удобнее так и делаю PS. xml шаблоны храню, как текстовые файлы в подкаталоге, имя, как правило, мнемоника понятная, если смотреть на оглавление. Это сделано, что бы редактором можно было поправить шаблон не привлекая меня. Редактор запускается из программы с таблицы "Список xml для ...", т.е. есть наименование для клиента и соответствующая мнемоника, под которой лежит файл xml (это скорее для меня, если лезу Far-ом)

Sergy: Идея интересная, нужно будет подумать... В общем, мне нужно научить мою систему электронному документообороту через СБИС. Нужно имеющиеся документы (заголовки и содержимое УПД отгрузки) выгружать в виде XML в заданный каталог. Пока думаю собрать данные в хэш и из него уже формировать xml, например:[pre2] { "НаимКонтр" => "ООО Ромашка", "ИннКонтр" => "1234567890", "НомерДок" => "123",; "Содержимое" => { "Строка1" => { "Наим" => "Печенье Чебурашка", "Кол"=>"2", "Цена"="134.65", "Налог" => "23.12" }, "Строка2" => { "Наим" => "Печенье Полет", "Кол"=>"3", "Цена"="434.65", "Налог" => "73.12" }, } "СуммаДок" => "4567.89", "ФиоДир" => "Иванов П.А.", ... } [/pre2]Если есть функция конвертации из хэша в xml, то отпадет смысл читать и разбирать XML по тегам, создавать и анализировать имена шаблонов-переменных. Кроме того, исключит ошибки в написании шаблонов.

SergKis: Sergy пишет Кроме того, исключит ошибки в написании шаблонов. Это очень оптимистическое отношение к процессу. Не знаю что такое система СБИС, у нас тут своя. Суть есть производитель и сети магазинов с системой xml заказов, в магазин отправляется xml исполнения заказов + система возвратных xml ордеров с товаром от магазина производителю. Магазины - это сети "Rimi", "Maxima", "Prizma" (правда ее выжили с рынка) и т.д. Магазины по разным городам и везде стоит типа "одна" система, но выдаваемые ею xml ключами могут оличаться, т.е для xml ордеров-заказа (прием), пришлось делать таблицу перекодироаки <тэг xml> => поле базы. Для отдаваемых xml в магазины пришлось построить описанную схему выше, т.к. даже в одной сети у разных магазинов, система принимает по разному тэги, там он обязателен, как пустой в др. месте на пустой ругается, что должен отсутствовать такой тэг, я уже молчу, что названия тэгов в отправляемых тэгах для магазинов одной сети могут быть разные. Единственное, что понял - это человеческий фактор (кто ставил\ настраивал) или разные версии программы, т.е. тут сменили. а тут нет, типа не добрались. PS. Составлять шаблоны оказалось просто, т.к. от каждого магазина есть описание xml - это pdf или excel файл. Беру и тупо ВСЕ данные тэгов просто нумерую, формируя ключ ^001, ^002, ... Немного надо повозиться, что бы выявить из др. таблицы файла описания, что есть обязательный или нет тэг и добавить в шаблон "-" перед ^, но не смотря на это, основное - это , как проглотит полученный xml их программа, если не проглотит, то даст сообщение и правим тогда свой шаблон PS2. Вот один из первых вариантов xml шаблона, без ini\hash ключей, где сразу из базы по макро берутся данные, сейчас создаю ini файл секцию с ключами ^100 = выражение ^101 = ... ... вместо макро из указанного шаблона. Для процедуры реализации указываю цикл тэг для исполнения DO WHILE !EOF() Пример шаблона, цикличный тэг <Line> ... </Line>[pre2] <?xml version="1.0" encoding="Utf-8"?> <Document-Invoice> <Document-Header> <DocumentReceiveDateTime>^mDtoS(Date(), "-")+"T"+Time()</DocumentReceiveDateTime> <DocumentProcessDateTime>^-</DocumentProcessDateTime> <DocumentID>^-</DocumentID> <DocumentUID>^-</DocumentUID> <DocumentType>INVOICE</DocumentType> <DocumentSource>W</DocumentSource> <OriginalFileName>^-</OriginalFileName> </Document-Header> <Invoice-Header> <InvoiceNumber>^AllTrim(NR_2)+AllTrim(NR_1)</InvoiceNumber> <InvoiceDate>^mDtoS(Date(), "-")</InvoiceDate> <InvoiceCurrency>^OH_3</InvoiceCurrency> <InvoicePaymentDueDate>^mDtoS(Date()+10, "-")</InvoicePaymentDueDate> <InvoicePaymentTerms>10</InvoicePaymentTerms> <InvoicePostDate>^-</InvoicePostDate> <DocumentFunctionCode>O</DocumentFunctionCode> <DocumentNameCode>380</DocumentNameCode> <Remarks>^GetFile("txt_remarks.txt",.T.)</Remarks> <Order> <BuyerOrderNumber>^OH_1</BuyerOrderNumber> <BuyerOrderDate>^OH_2</BuyerOrderDate> <SellerOrderNumber>^-</SellerOrderNumber> </Order> <Delivery> <DeliveryLocationNumber>^OP_9</DeliveryLocationNumber> <CodeBySeller>^-</CodeBySeller> <CodeByBuyer>^-</CodeByBuyer> <Name>^-</Name> <StreetAndNumber>^-</StreetAndNumber> <CityName>^-</CityName> <Country>^-</Country> <DeliveryDate>^mDtoS(Date(), "-")</DeliveryDate> <DespatchNumber>^AllTrim(NR_2)+AllTrim(NR_1)</DespatchNumber> </Delivery> </Invoice-Header> <Document-Parties> <Sender> <ILN>^OP_6</ILN> </Sender> <Receiver> <ILN>^OP_1</ILN> </Receiver> <Creator> <SystemUniqueCode>^-</SystemUniqueCode> <Name>^-</Name> <E-mail>^-</E-mail> <CreationType>^-</CreationType> </Creator> </Document-Parties> <Invoice-Parties> <Buyer> <ILN>^OP_1</ILN> <TaxID>^-</TaxID> <CodeBySeller>^-</CodeBySeller> <UtilizationRegisterNumber>^-</UtilizationRegisterNumber> <Name>^-</Name> <StreetAndNumber>^gT("StreetR")</StreetAndNumber> <CityName>^-</CityName> <PostalCode>^-</PostalCode> <Country>^-</Country> </Buyer> <Payer> <ILN>^OP_1</ILN> <TaxID>^-</TaxID> <CodeBySeller>^-</CodeBySeller> <CodeByBuyer>^-</CodeByBuyer> <UtilizationRegisterNumber>^-</UtilizationRegisterNumber> <Name>^-</Name> <StreetAndNumber>^gT("StreetR")</StreetAndNumber> <CityName>^-</CityName> <PostalCode>^-</PostalCode> <Country>^-</Country> </Payer> <Invoicee> <ILN>^OP_1</ILN> <TaxID>^-</TaxID> <CodeBySeller>^-</CodeBySeller> <CodeByBuyer>^-</CodeByBuyer> <UtilizationRegisterNumber>^-</UtilizationRegisterNumber> <Name>^-</Name> <StreetAndNumber>^gT("StreetR")</StreetAndNumber> <CityName>^-</CityName> <PostalCode>^-</PostalCode> <Country>^-</Country> </Invoicee> <Seller> <ILN>^OP_6</ILN> <TaxID>^-</TaxID> <CodeBySeller>^-</CodeBySeller> <CodeByBuyer>^-</CodeByBuyer> <UtilizationRegisterNumber>^-</UtilizationRegisterNumber> <Name>^-</Name> <StreetAndNumber>^gT("StreetB")</StreetAndNumber> <CityName>^-</CityName> <PostalCode>^-</PostalCode> <Country>^-</Country> <OperatorDetails> <Name>^-</Name> <TelephoneNumber>^-</TelephoneNumber> <E-mail>^-</E-mail> </OperatorDetails> </Seller> <Payee> <ILN>^OP_6</ILN> <TaxID>^-</TaxID> <AccountNumber>^-</AccountNumber> <UtilizationRegisterNumber>^-</UtilizationRegisterNumber> <CodeBySeller>^-</CodeBySeller> <CodeByBuyer>^-</CodeByBuyer> <Name>^-</Name> <StreetAndNumber>^gT("StreetB")</StreetAndNumber> <CityName>^-</CityName> <Country>^-</Country> </Payee> </Invoice-Parties> <Invoice-Lines> <Line> <Line-Item> <LineNumber>^u2s(LN_1)</LineNumber> <EAN>^AllTrim(LN_2)</EAN> <SupplierItemCode>^-</SupplierItemCode> <ItemDescription>^LN_13</ItemDescription> <InvoiceQuantity>^iif(empty(LN_14), LN_7, LN_14)</InvoiceQuantity> <InvoiceUnitNetPrice>^iif(empty(LN_15), LN_10, LN_15)</InvoiceUnitNetPrice> <UnitOfMeasure>^LN_24</UnitOfMeasure> <InvoicedUnitPackSize>^-</InvoicedUnitPackSize> <TaxRate>^LN_22</TaxRate> <TaxCategoryCode>S</TaxCategoryCode> <TaxAmount>^LN_23</TaxAmount> <NetAmount>^iif(empty(LN_16), LN_11, LN_16)</NetAmount> </Line-Item> <Line-Delivery> <DeliveryLocationNumber>^OP_9</DeliveryLocationNumber> <CodeByBuyer>^-</CodeByBuyer> <Name>^-</Name> <DeliveryDate>^mDtoS(Date()+10, "-")</DeliveryDate> <DespatchNumber>^AllTrim(NR_2)+AllTrim(NR_1)</DespatchNumber> </Line-Delivery> <Line-AdditionalInformation> <CountryOfOrigin>^-</CountryOfOrigin> </Line-AdditionalInformation> </Line> </Invoice-Lines> <Invoice-Summary> <TotalLines>^OS_7</TotalLines> <TotalNetAmount>^OS_6</TotalNetAmount> <TotalTaxAmount>^OS_4</TotalTaxAmount> <TotalRounding>^-</TotalRounding> <TotalGrossAmount>^OS_6+OS_4</TotalGrossAmount> <Tax-Summary> <Tax-Summary-Line> <TaxRate>^OS_5</TaxRate> <TaxCategoryCode>S</TaxCategoryCode> <TaxAmount>^OS_4</TaxAmount> <TaxableAmount>^OS_6</TaxableAmount> </Tax-Summary-Line> </Tax-Summary> </Invoice-Summary> </Document-Invoice> [/pre2]


SergKis: Sergy пишет отпадет смысл читать и разбирать XML по тегам Для получения представленного Hash, надо иметь какой то источник (hash или ini файл), где будет соответствие ключа (имя тэга) и выражение получение значения для этого ключа. И чем это отличается от шаблона, т.е. [pre2] { "НаимКонтр" => "ООО Ромашка", "ИннКонтр" => "1234567890", "НомерДок" => "123",; "Содержимое" => { "Строка1" => { "Наим" => "Печенье Чебурашка", "Кол"=>"2", "Цена"="134.65", "Налог" => "23.12" }, "Строка2" => { "Наим" => "Печенье Полет", "Кол"=>"3", "Цена"="434.65", "Налог" => "73.12" }, } "СуммаДок" => "4567.89", "ФиоДир" => "Иванов П.А.", ... } просит наличия чего то такого, например в ini [BODY] While = Содержимое // ключ цикла и описание строк самого цикла где то и как то ... [VALUES] НаимКонтр = ООО "Ромашка" // или имя поля откуда взять ИннКонтр = 1234567890 ... СуммаДок = 4567.89 ... [/pre2] Со временем эти ключи могут меняться, не держать же их в prg, можно применить тут использование hrb и накапливать как библиотеку для формирования xml. Это будут hrb iшаблоны.

Sergy: SergKis пишет: Для получения представленного Hash, надо иметь какой то источник (hash или ini файл), где будет соответствие ключа (имя тэга) и выражение получение значения для этого ключа. И чем это отличается от шаблона, т.е. Хм, логично… Пошел думать

Sergy: Сергей, возник вопрос: вот есть накладная, которую нужно передать в виде xml. Есть некий набор обязательных и необязательных полей, задаваемых шаблоном. Это понятно. А как ты задаешь в шаблоне итерацию по строкам с товаром, ведь их количество заранее неизвестно ? Вижу у тебя тэг <Line>. Получается, что ты еще анализируешь и содержимое тэгов ? И где-то жестко заложено, что <Line> обрабатывать в цикле, а остальные - пропускать без изменения в выходной файл, подставляя лишь значения между тэгами ? А если <Line> завтра окажется в каком-то из новых шаблонов контрагента как рабочий тэг ?



полная версия страницы