Ad Widget

Collapse

XML XPath - пустое значение

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • a.ratnikov
    Junior Member
    • Dec 2018
    • 13

    #1

    XML XPath - пустое значение

    Есть следующая проблема:
    Есть ссылка, которая выдает строку:
    <boolean xmlns="http://schemas.microsoft.com/2003/10/Serialization/">true</boolean> Через Preprocessing steps необходимо забирать значение true или false. Соответсвенно через различные онлайн тесты типа https://codebeautify.org/Xpath-Tester опытным путем узнал, что необходимое выражение string() Но если я ввожу в string() в параметры препроцессинга XML XPath то получаю пустое значение. Как можно правильно забрать эти значения? Ранее я сделал это через Trim, но это заняло 9 шагов. Версия Zabbix 4.0.1
  • Semiadmin
    Senior Member
    • Oct 2014
    • 1625

    #2
    Проблема - в атрибуте xmlns, который, как я понимаю, переопределяет пространство имен и мешает работе XPath. Если убрать его или заменить на любой другой, то все работает.
    А можно просто распарсить строку регуляркой, без XML XPath.

    Comment

    • a.ratnikov
      Junior Member
      • Dec 2018
      • 13

      #3
      Originally posted by Semiadmin
      Проблема - в атрибуте xmlns, который, как я понимаю, переопределяет пространство имен и мешает работе XPath. Если убрать его или заменить на любой другой, то все работает.
      А можно просто распарсить строку регуляркой, без XML XPath.
      Да, так в итоге и сделал.
      Регулярное выражение <.*>(.*)<.*>$ параметр \1
      Далее из boolean to decimal.

      Вопрос такой теперь. Если у счетчика статус Connection refused - могу я присваивать значение 0?

      Comment

      • Semiadmin
        Senior Member
        • Oct 2014
        • 1625

        #4
        Иначе говоря, true - 1, все остальное - 0? Боюсь, что препроцессингом не выйдет, но можно через вычисляемый айтем с функцией str или regexp

        Comment

        • Kos
          Senior Member
          Zabbix Certified SpecialistZabbix Certified Professional
          • Aug 2015
          • 3404

          #5
          Originally posted by Semiadmin
          Иначе говоря, true - 1, все остальное - 0? Боюсь, что препроцессингом не выйдет, но можно через вычисляемый айтем с функцией str или regexp
          Не, ну так-то регуляркой за пару шагов сделать, вроде, можно.
          Скажем, "^true$" заменяем на "1", а следующим шагом "^[^1].*$" заменяем на "0".
          Только, боюсь, что автора вопроса интересовала ситуация, когда он вообще значение получить не может - до проверяемой им ссылки не удаётся достучаться. Я не знаю, что будет происходить в такой ситуации (айтем перейдёт в статус "not supported"?).

          Comment

          • Semiadmin
            Senior Member
            • Oct 2014
            • 1625

            #6
            Originally posted by Kos
            Не, ну так-то регуляркой за пару шагов сделать, вроде, можно.
            Скажем, "^true$" заменяем на "1", а следующим шагом "^[^1].*$" заменяем на "0".
            Там, к сожалению, не так все просто, коллега Kos. Шаги выполняются последовательно. Т.е. ^true$ заменить на 1 можно, но если будет false, то второго шага не будет, будет неподдерживаемый айтем после первого шага.

            Comment

            • Kos
              Senior Member
              Zabbix Certified SpecialistZabbix Certified Professional
              • Aug 2015
              • 3404

              #7
              Originally posted by Semiadmin
              Там, к сожалению, не так все просто, коллега Kos. Шаги выполняются последовательно. Т.е. ^true$ заменить на 1 можно, но если будет false, то второго шага не будет, будет неподдерживаемый айтем после первого шага.
              Блин, действительно. Спасибо, Semiadmin, не знал. И в самом деле "не так всё просто", как казалось.
              Тем не менее, мне удалось за 3 шага с помощью регулярных выражений любую строку, которая начинается с "true", перевести в единицу, а любую другую - в ноль:
              № шага Регулярное выражение Подстановка
              1 ^(true)?(?:.*)$ \10
              2 ^(true0)?(0)?$ \21
              3 ^(.).*$ \1
              Логика тут такая.

              На первом шаге ищем подстроку "true" в начале строки; всё, что нашли, кроме неё, -- убираем, а справа дописываем ноль.
              Промежуточный результат после первого шага:
              true -> true0
              true1 -> true0
              0true -> 0
              false -> 0
              Connection refused -> 0
              ""
              (пустая строка) -> 0

              На втором шаге ищем в начале строки подстроку "true0" (ведь ноль справа мы дописали перед этим), если нашли, то заменяем единицей. А если не нашли - то найдём один лишь нолик, который и переносим в результат, дописывая единицу справа от него.
              Промежуточный результат после второго шага:
              true0 -> 1
              0 -> 01


              Ну а на третьем шаге лишь выдёргиваем первый символ из оставшейся строки: либо ноль, либо единицу.

              Наверное, можно как-то покрасивее сделать, у меня пока что получилось лишь так.
              Основной приём, который тут используется, -- это выражение вида "(...)?" -- оно создаёт группу, которой в исходной строке может и не быть соответствия. Но на неё при этом можно ссылаться при подстановках ("\1", "\2") -- если она не найдена в исходной строке, то подставится пустая строка.

              Comment

              • Semiadmin
                Senior Member
                • Oct 2014
                • 1625

                #8
                Kos, здорово. Я думал над чем-то подобным, но не довел решение до конца. Возьму на вооружение, спасибо.

                Comment

                Working...