Arhn - архитектура программирования

Обработка XML на страницах ASP — часть 2

Ребята .... Это продолжение аналогичного вопроса, который я недавно задал. Как я могу получить конкретное значение из XML-структуры, не перемещаясь по структуре и не перебирая все дочерние узлы? Было предложено использовать XPath.

Предположим следующую упрощенную структуру XML:

<MyWeather>
    <sensor location="Front Entry">
    <reading label="Temperature">
        <title>Front Entry</title>
        <label>Temperature</label>
        <value>54</value>
        <units>F</units>
        <lastUpdate>05/27/2013 12:23 AM</lastUpdate>
    </reading>
    <reading label="Humidity">
        <title>Front Entry</title>
        <label>Humidity</label>
        <value>66</value>
        <units>%</units>
        <lastUpdate>05/27/2013 12:23 AM</lastUpdate>
    </reading>
</sensor>
<sensor location="Patio">
    <reading label="Temperature">
        <title>Patio</title>
        <label>Temperature</label>
        <value>46</value>
        <units>F</units>
        <lastUpdate>05/27/2013 12:23 AM</lastUpdate>
    </reading>
    <reading label="Humidity">
        <title>Patio</title>
        <label>Humidity</label>
        <value>93</value>
        <units>%</units>
        <lastUpdate>05/27/2013 12:23 AM</lastUpdate>
    </reading>

    </sensor>
</MyWeather>

Вот часть моей ASP-страницы:

<%
xmlDoc = CreateObject("Msxml2.DOMDocument")
xmldoc.setProperty ("ServerHTTPRequest", true)
xmlDoc.setProperty ("ProhibitDTD", False)
xmlDoc.validateOnParse = true

'    Filename is a sting variable containing the URL

xmlDoc.async = "False"
xmlDoc.load(FileName)

'    Error and return code processing done here but removed 

For Each el In xmldoc.childNodes
    if el.childnodes.length <> 0 then
    response.write ("<table align='center' class='auto-style1'>")
    for each el2 in el.childnodes
        Response.write("<tr><td>" & el2.getattribute("location") & "</td><td></td></tr>")
        for each el3 in el2.childnodes
            for each el4 in el3.childnodes
            if el4.nodename = "value" then 
            Response.write("<tr><td></td><td>" & el3.getattribute("label") & " " & el4.text & " " & el4.nextSibling.text & "</td></tr>")
            exit for
              end if
          next
          next
      next
    response.write ("</table>")
    end if
  Next
xmlDoc = Nothing

%>

Мой вопрос относится к коду в разделе "Для каждого el4 в...". Вы видите, что я перебираю дочерние узлы, пока не найду «значение». Затем я вывожу это значение тега, и, поскольку я знаю, что следующий тег (пока что они не изменят его), является тегом «единиц», который я использую nextsibling для получения этого значения. Этот код работает!

Я хотел бы знать следующее: существует ли более прямой путь к этим двум значениям тега для любой комбинации Расположение датчика и Чтение метки без моего процесса итерации.

У меня есть несколько других случаев, когда мне может потребоваться перебрать более 50 элементов, чтобы найти тег, который я ищу.

Я добавил этот код xPath на основе рекомендации из моего предыдущего вопроса. Это, если бы это сработало, заменило бы «для каждого el4 в цикле el3.childnodes» выше.

xmlDoc.setProperty ("SelectionLanguage", "XPath")

                oNode = xmldoc.selectSingleNode("//reading[@label='Temperaure']/units")
                o2Node = xmldoc.selectSingleNode("//reading[@label='Temperaure']/value")
                if oNode is nothing or o2node is nothing then
                    Response.write("<tr><td></td><td> Nothing found for value or units </td><td>" & el3.getattribute("label") & "</tr>") 
                  else
                    Response.write("<tr><td></td><td>" & el3.getattribute("label") & " " & o2Node.text & " " & oNode.text & "</td></tr>")
                  end if    

Однако это не сработало для меня. Я пробовал несколько вариантов: без знака @ и с полным путем в операторах oNode, т.е. /MyWeather/sensor/reading/...

Моя проверка на пустой oNode и/или O2Node всегда верна.

Есть идеи?..... РДК

01.06.2013

  • Вы действительно интересуетесь Temperaure? Тогда вам лучше исправить эту опечатку. 02.06.2013

Ответы:


1

Если вы уже немного прошлись по дереву со всеми вашими вложенными циклами For Each, то для замены еще одного вложенного For Each вам нужно убедиться, что вы вызываете selectSingleNode для переменной во внешнем For Each и используете относительный путь, например.

  Response.Write el3.selectSingleNode("value").text

Я настоятельно рекомендую вообще не использовать childNodes, а просто убедиться, что вы используете selectNodes с путем к интересующим вас элементам, таким образом, будет намного яснее, какие узлы элементов вы обрабатываете; например, если вы действительно проверяете, что ввод XML был успешно проанализирован с проверкой ошибок, тогда

For Each el In xmldoc.childNodes
    if el.childnodes.length <> 0 then
    response.write ("<table align='center' class='auto-style1'>")

является излишним, так как правильно сформированный XML-документ всегда имеет дочерний узел корневого элемента, поэтому, как только вы проверите, например,

  If xmlDoc.parseError.errorCode = 0 Then
    Response.Write ("<table align='center' class='auto-style1'>")

должно хватить.

Если затем вы хотите получить доступ к корневому элементу (в вашем случае к элементу MyWheater), достаточно использовать xmlDoc.documentElement.

Далее вы можете использовать

  For Each sensor In xmlDoc.documentElement.selectNodes("sensor")
    Dim tr
    Set tr = sensor.selectSingleNode("reading[@label = 'Temperature']")
    Response.Write tr.selectSingleNode("value").text & " " & tr.selectSingleNode("unit").text
  Next

Единственная проблема с XML - это пространства имен, если ваш реальный XML имеет такие атрибуты, как xmlns="http://example.com", или если какое-либо DTD, которое у вас есть, устанавливает такие атрибуты как значения по умолчанию, тогда с MSXML вам нужно использовать, например.

  xmlDoc.setProperty "SelectionNamespaces", "xmlns:df='http://example.com'"

и далее вам нужно использовать этот префикс (например, df) для уточнения имен элементов в ваших выражениях XPath, переданных в selectNodes и selectSingleNode, т.е.

  For Each sensor In xmlDoc.documentElement.selectNodes("df:sensor")
    Dim tr
    Set tr = sensor.selectSingleNode("df:reading[@label = 'Temperature']")
    Response.Write tr.selectSingleNode("df:value").text & " " & tr.selectSingleNode("df:unit").text
  Next
02.06.2013
  • ВОТ ЭТО ДА!!!! Спасибо за подробный и хорошо документированный ответ. Я впечатлен. К сожалению, я собираюсь уехать на несколько дней, поэтому я не смогу сразу изучить и применить ваши предложения. Я вернусь, когда я попробовал их. Спасибо еще раз. 02.06.2013
  • Мартин..... Еще раз спасибо за ваш ответ. Я изучил ваши комментарии и успешно применил их к своему проекту. Опять респект. Я также должен поблагодарить Йенса Эрата за обнаружение моей опечатки, которая, безусловно, вызвала некоторые из моих предыдущих проблем. 06.06.2013
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..