Ad Widget

Collapse

Конвертация XML в JSON в правиле обнаружения

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • igor-box
    Junior Member
    • Jan 2021
    • 15

    #1

    Конвертация XML в JSON в правиле обнаружения

    Здравствуйте.
    Такая проблема: есть видеорегистратор. Надо его мониторить заббиксом. Создаю правило обнаружения и http запросом получаю информацию с него в виде XML.

    Click image for larger version

Name:	11.png
Views:	279
Size:	20.0 KB
ID:	417337

    Code:
    <?xml version="1.0" encoding="UTF-8" ?>
    <InputProxyChannelStatusList>
    <InputProxyChannelStatus>
    <id>1</id>
    <online>true</online>
    <streamingProxyChannelIdList>
    </streamingProxyChannelIdList>
    <relatedIOProxy>
    <inputProxyPortIdList>
    </inputProxyPortIdList>
    <outputProxyPortIdList>
    </outputProxyPortIdList>
    </relatedIOProxy>
    <chanDetectResult>connect</chanDetectResult>
    <SecurityStatus>
    <PasswordStatus>weak</PasswordStatus>
    </SecurityStatus>
    </InputProxyChannelStatus>
    </InputProxyChannelStatusList>
    дальше, как я понимаю, надо эти данные конвертировать в JSON? Подскажите как это сделать?
  • igor-box
    Junior Member
    • Jan 2021
    • 15

    #2
    Подскажите кто-нибудь

    Comment

    • Hamardaban
      Senior Member
      Zabbix Certified SpecialistZabbix Certified Professional
      • May 2019
      • 2713

      #3
      Если формально ответить на вопрос - то в предобработке есть конвертер xml to json. Или через JS делайте как угодно.
      А если подумать, то лучше скажите что вы хотите получить то? Какую метрику / метрики?

      Comment

      • Semiadmin
        Senior Member
        • Oct 2014
        • 1625

        #4
        Конвертера XML to JSON в препроцессинге, к сожалению, нет. Есть только CSV to JSON. Более того, когда я раз столкнулся с подобной проблемой, мне не удалось найти конвертер на JS, который бы работал на движке Duktape. Если кто подскажет рабочее решение - было бы здорово. Есть, конечно, встроенный парсер XML XPath, но он не годится для LLD. А если нужно LLD.... Я как-то раз, не найдя лучшего решения, разобрал XML в JS-препроцессинге регулярками, как обычный текст. Очевидная альтернатива - использовать не http agent, а external check с curl и, к примеру, xmllint.
        Last edited by Semiadmin; 25-01-2021, 21:20.

        Comment


        • Hamardaban
          Hamardaban commented
          Editing a comment
          пардон! конечно я напутал...
          Недавно тоже возился с преобразованием XML >JSON.
          "победил" получив данные от системы не в XML, а в CSV - вот ложная память и всплыла....
          Last edited by Hamardaban; 26-01-2021, 12:48.
      • igor-box
        Junior Member
        • Jan 2021
        • 15

        #5
        Originally posted by Semiadmin
        Конвертера XML to JSON в препроцессинге, к сожалению, нет. Есть только CSV to JSON. Более того, когда я раз столкнулся с подобной проблемой, мне не удалось найти конвертер на JS, который бы работал на движке Duktape. Если кто подскажет рабочее решение - было бы здорово. Есть, конечно, встроенный парсер XML XPath, но он не годится для LLD. А если нужно LLD.... Я как-то раз, не найдя лучшего решения, разобрал XML в JS-препроцессинге регулярками, как обычный текст. Очевидная альтернатива - использовать не http agent, а external check с curl и, к примеру, xmllint.
        Соглашусь, конвертера XML to JSON в препроцессинге нет. Так же пробовал скрипты на JS для этого, но они не заработали. Выдавали ошибки. А вот про "разобрал XML в JS-препроцессинге регулярками, как обычный текст" не понял. Что это даст в LLD?

        Comment

        • igor-box
          Junior Member
          • Jan 2021
          • 15

          #6
          Originally posted by Hamardaban
          Если формально ответить на вопрос - то в предобработке есть конвертер xml to json. Или через JS делайте как угодно.
          А если подумать, то лучше скажите что вы хотите получить то? Какую метрику / метрики?
          Есть xml файл, где id это номер камеры.

          Code:
          <?xml version="1.0" encoding="UTF-8" ?>
          <InputProxyChannelStatusList>
          <InputProxyChannelStatus>
          <id>1</id>
          <online>true</online>
          <streamingProxyChannelIdList>
          </streamingProxyChannelIdList>
          <relatedIOProxy>
          <inputProxyPortIdList>
          </inputProxyPortIdList>
          <outputProxyPortIdList>
          </outputProxyPortIdList>
          </relatedIOProxy>
          <chanDetectResult>connect</chanDetectResult>
          <SecurityStatus>
          <PasswordStatus>weak</PasswordStatus>
          </SecurityStatus>
          </InputProxyChannelStatus>
          </InputProxyChannelStatusList>
          надо по LLD находить все камеры (id) а потом в принципе нужны лишь два значения каждой камеры: <online>true</online> и <chanDetectResult>connect</chanDetectResult>

          Comment

          • Semiadmin
            Senior Member
            • Oct 2014
            • 1625

            #7
            Originally posted by igor-box
            А вот про "разобрал XML в JS-препроцессинге регулярками, как обычный текст" не понял. Что это даст в LLD?
            Собственно, даст на выходе JS-скрипта тот самый искомый JSON со списком id камер. Не конвертированый в JSON исходный XML, а только id и LLD макрос. А в прототипах айтемов уже можно использовать для парсинга XML XPath.

            Comment

            • igor-box
              Junior Member
              • Jan 2021
              • 15

              #8
              Originally posted by Semiadmin
              Собственно, даст на выходе JS-скрипта тот самый искомый JSON со списком id камер. Не конвертированый в JSON исходный XML, а только id и LLD макрос. А в прототипах айтемов уже можно использовать для парсинга XML XPath.
              Все равно не понимаю до конца ))) Не могли бы рассказать поподробнее конкретно на моем примере?

              Comment

              • Semiadmin
                Senior Member
                • Oct 2014
                • 1625

                #9
                Для этого, видимо, надо привести пример XML с несколькими id. В вашем примере id один и в этом случае не очень понятно, зачем его дискаверить.

                Comment

                • igor-box
                  Junior Member
                  • Jan 2021
                  • 15

                  #10
                  Originally posted by Semiadmin
                  Для этого, видимо, надо привести пример XML с несколькими id. В вашем примере id один и в этом случае не очень понятно, зачем его дискаверить.
                  Code:
                  <?xml version="1.0" encoding="UTF-8" ?>
                  <InputProxyChannelStatusList>
                  <InputProxyChannelStatus>
                  <id>1</id>
                  <sourceInputPortDescriptor>
                  <proxyProtocol>Custom 1</proxyProtocol>
                  <addressingFormatType>ipaddress</addressingFormatType>
                  <srcInputPort>1</srcInputPort>
                  <streamType>auto</streamType>
                  <deviceID></deviceID>
                  </sourceInputPortDescriptor>
                  <online>true</online>
                  <streamingProxyChannelIdList>
                  </streamingProxyChannelIdList>
                  <relatedIOProxy>
                  <inputProxyPortIdList>
                  </inputProxyPortIdList>
                  <outputProxyPortIdList>
                  </outputProxyPortIdList>
                  </relatedIOProxy>
                  <chanDetectResult>connect</chanDetectResult>
                  <SecurityStatus>
                  <PasswordStatus>weak</PasswordStatus>
                  </SecurityStatus>
                  </InputProxyChannelStatus>
                  <InputProxyChannelStatus>
                  <id>2</id>
                  <sourceInputPortDescriptor>
                  <proxyProtocol>Custom 2</proxyProtocol>
                  <addressingFormatType>ipaddress</addressingFormatType>
                  <srcInputPort>1</srcInputPort>
                  <streamType>auto</streamType>
                  <deviceID></deviceID>
                  </sourceInputPortDescriptor>
                  <online>true</online>
                  <streamingProxyChannelIdList>
                  </streamingProxyChannelIdList>
                  <relatedIOProxy>
                  <inputProxyPortIdList>
                  </inputProxyPortIdList>
                  <outputProxyPortIdList>
                  </outputProxyPortIdList>
                  </relatedIOProxy>
                  <chanDetectResult>connect</chanDetectResult>
                  <SecurityStatus>
                  <PasswordStatus>weak</PasswordStatus>
                  </SecurityStatus>
                  </InputProxyChannelStatus>
                  ...
                  <InputProxyChannelStatus>
                  <id>13</id>
                  <sourceInputPortDescriptor>
                  <proxyProtocol>Custom 13</proxyProtocol>
                  <addressingFormatType>ipaddress</addressingFormatType>
                  <srcInputPort>1</srcInputPort>
                  <streamType>auto</streamType>
                  <deviceID></deviceID>
                  </sourceInputPortDescriptor>
                  <online>false</online>
                  <streamingProxyChannelIdList>
                  </streamingProxyChannelIdList>
                  <relatedIOProxy>
                  <inputProxyPortIdList>
                  </inputProxyPortIdList>
                  <outputProxyPortIdList>
                  </outputProxyPortIdList>
                  </relatedIOProxy>
                  <chanDetectResult>netUnreachable</chanDetectResult>
                  <SecurityStatus>
                  <PasswordStatus>weak</PasswordStatus>
                  </SecurityStatus>
                  </InputProxyChannelStatus>
                  </InputProxyChannelStatusList>

                  Comment

                  • Hamardaban
                    Senior Member
                    Zabbix Certified SpecialistZabbix Certified Professional
                    • May 2019
                    • 2713

                    #11
                    Набрел вот на такую работающую(!) штуку: https://github.com/kawanet/from-xml . В dist лежит обфусированная в одну строку функция

                    в припроцессинге JS делаем как-то так:

                    Code:
                    // собственно описание функции fromXML
                    var fromXML;!function(r){function t(r,t){return a(n(r),t)}function n(r){function t(r){var t=r.length,f=r[0];if("/"===f)for(var u=r.replace(/^\/|[\s\/].*$/g,"").toLowerCase();c.length;){var a=l.n&&l.n.toLowerCase();if(l=c.pop(),a===u)break} else if("?"===f)n({n:"?",r:r.substr(1,t-2)});else if("!"===f)"[CDATA["===r.substr(1,7)&&"]]"===r.substr(-2)?e(r.substr(8,t-10)):n({n:"!",r:r.substr(1)});else{var o=s(r);n(o),"/"===r[t-1]?o.c=1:(c.push(l),l=o)}}function n(r){l.f.push(r)}function e(r){r=f(r),r&&n(u(r))}for(var a=String.prototype.split.call(r,/<([^!<>?](?:'[\S\s]*?'|"[\S\s]*?"|[^'"<>])*|!(?:--[\S\s]*?--|\[[^\[\]'"<>]+\[[\S\s]*?]]|DOCTYPE[^\[<>]*?\[[\S\s]*?]|(?:ENTITY[^"<>]*?"[\S\s]*?")?[\S\s]*?)|\?[\S\s]*?\?)>/),o=a.length,i={f:[]},l=i,c=[],p=0;p<o;){var v=a[p++];v&&e(v);var g=a[p++];g&&t(g)}return i}function s(r){var t={f:[]};r=r.replace(/\s*\/?$/,"");var n=r.search(/[\s='"\/]/);return n<0?t.n=r:(t.n=r.substr(0,n),t.t=r.substr(n)),t}function e(r,t){if(r.t){for(var n,s,e=r.t.split(/([^\s='"]+(?:\s*=\s*(?:'[\S\s]*?'|"[\S\s]*?"|[^\s'"]*))?)/),a=e.length,i=0;i<a;i++){var c=f(e[i]);if(c){n||(n={});var p=c.indexOf("=");if(p<0)c=l+c,s=null;else{s=c.subs tr(p+1).replace(/^\s+/,""),c=l+c.substr(0,p).replace(/\s+$/,"");var v=s[0],g=s[s.length-1];v!==g||"'"!==v&&'"'!==v||(s=s.substr(1,s.length-2)),s=u(s)}t&&(s=t(c,s)),o(n,c,s)}}return n}}function f(r){return r&&r.replace(/^\s+|\s+$/g,"")}function u(r){return r.replace(/(&(?:lt|gt|amp|apos|quot|#(?:\d{1,6}|x[0-9a-fA-F]{1,5}));)/g,function(r){if("#"===r[1]){var t="x"===r[2]?parseInt(r.substr(3),16):parseInt(r.substr(2),10);if(t>-1)return String.fromCharCode(t)}return i[r]||r})}function a(r,t){if("string"==typeof r)return r;var n=r.r;if(n)return n;var s,f=e(r,t),u=r.f,i=u.length;if(f||i>1)s=f||{},u.fo rEach(function(r){"string"==typeof r?o(s,c,r):o(s,r.n,a(r,t))});else if(i){var l=u[0];if(s=a(l,t),l.n){var p={};p[l.n]=s,s=p}}else s=r.c?null:"";return t&&(s=t(r.n||"",s)),s}function o(r,t,n){if("undefined"!=typeof n){var s=r[t];s instanceof Array?s.push(n):t in r?r[t]=[s,n]:r[t]=n}}var i={"&amp;":"&","&lt;":"<","&gt;":">","&apos;":"'", "&quot;":'"'},l="@",c="#";r.fromXML=fromXML=t}("ob ject"==typeof exports&&exports||{});
                    // применение - получаем объект JS
                    var data = fromXML(value);
                    // можем делать с объектом все преобразования
                    // например убрать лишнее или обернуть в data
                    // преобразовываем в JSON
                    return JSON.stringify(data);
                    Last edited by Hamardaban; 26-01-2021, 14:29.

                    Comment


                    • Semiadmin
                      Semiadmin commented
                      Editing a comment
                      Работает, спасибо! Сохранил, вещь хорошая, пригодится.
                  • Semiadmin
                    Senior Member
                    • Oct 2014
                    • 1625

                    #12
                    Интересно, надо попробовать, как это работает.
                    Я пока накидал простенький скрипт, получающий json с нужными значениями для данного XML:
                    Code:
                    a = value.match(/<id>(\d+)<\/id>[\s\S]*?<online>(\w+)<\/online>[\s\S]*?<chanDetectResult>(\w+)</g).toString();
                    b = a.replace(/<id>(\d+)<[\s\S]*?<online>(\w+)<[\s\S]*?<chanDetectResult>(\w+)</g,'{"id":"$1","online":"$2","chanDetectResult":"$3 "}');
                    return b.replace(/(.*)/,'[$1]')
                    в результате:
                    Code:
                    [{
                    "id": "1",
                    "online": "true",
                    "chanDetectResult": "connect"
                    }, {
                    "id": "2",
                    "online": "true",
                    "chanDetectResult": "connect"
                    }]

                    Comment

                    • igor-box
                      Junior Member
                      • Jan 2021
                      • 15

                      #13
                      Спасибо. Завтра попробую оба способа. Обязательно отпишусь по итогу.

                      Comment

                      • igor-box
                        Junior Member
                        • Jan 2021
                        • 15

                        #14
                        Originally posted by Hamardaban
                        Набрел вот на такую работающую(!) штуку: https://github.com/kawanet/from-xml . В dist лежит обфусированная в одну строку функция

                        в припроцессинге JS делаем как-то так:
                        Что-то я запутался. Делаю так:

                        Создаю правило обнаружения:

                        Click image for larger version

Name:	1.png
Views:	213
Size:	19.2 KB
ID:	417533

                        Click image for larger version

Name:	2.png
Views:	197
Size:	24.0 KB
ID:	417534

                        Click image for larger version

Name:	3.png
Views:	202
Size:	13.4 KB
ID:	417535

                        Делаю тест этого правила. На выходе получаю:

                        Code:
                        {"InputProxyChannelStatusList":{"InputProxyChannel Status":[{"id":"1","sourceInputPortDescriptor":{"proxyProto col":"Custom 1","addressingFormatType":"ipaddress","ipAddress": "***","managePortNo":"554","srcInputPort":"1","use rName":"***","streamType":"auto","deviceID":""},"o nline":"true","streamingProxyChannelIdList":"","re latedIOProxy":{"inputProxyPortIdList":"","outputPr oxyPortIdList":""},"chanDetectResult":"connect","S ecurityStatus":{"PasswordStatus":"weak"}},{"id":"2 ","sourceInputPortDescriptor":{"proxyProtocol":"Cu stom 2","addressingFormatType":"ipaddress","ipAddress": "***","managePortNo":"554","srcInputPort":"1","use rName":"***","streamType":"auto","deviceID":""},"o nline":"true","streamingProxyChannelIdList":"","re latedIOProxy":{"inputProxyPortIdList":"","outputPr oxyPortIdList":""},"chanDetectResult":"connect","S ecurityStatus":{"PasswordStatus":"weak"}},
                        ...
                        {"id":"13","sourceInputPortDescriptor":{"proxyProt ocol":"Custom 13","addressingFormatType":"ipaddress","ipAddress" :"***","managePortNo":"554","srcInputPort":"1","us erName":"***","streamType":"auto","deviceID":""}," online":"false","streamingProxyChannelIdList":""," relatedIOProxy":{"inputProxyPortIdList":"","output ProxyPortIdList":""},"chanDetectResult":"netUnreac hable","SecurityStatus":{"PasswordStatus":"weak"}}]}}
                        Далее создаю прототип элементов данных:

                        Click image for larger version

Name:	4.png
Views:	198
Size:	33.4 KB
ID:	417536

                        Что не так?

                        Comment

                        • Semiadmin
                          Senior Member
                          • Oct 2014
                          • 1625

                          #15
                          LLD макрос должен быть параметром ключа, ну или частью параметра. Как-то так: camera_status[{#CAMERA_ID}]

                          Comment

                          Working...