Выбор глубоко вложенной ссылки с помощью запроса xpath - PullRequest
0 голосов
/ 24 апреля 2011
<body class="en-us">   <div id="wrapper">
    <div id="content">
      <div class="content-top">
        <div class="content-bot">
          <div id="profile-wrapper" class=
          "profile-wrapper profile-wrapper-horde">
            <div class="profile-sidebar-anchor">
              <div class="profile-sidebar-outer">
                <div class="profile-sidebar-inner">
                  <div class="profile-sidebar-contents">
                    <div class="profile-sidebar-crest">
                      <a href="/wow/en/character/some-server/sometoon/" rel="np" class="profile-sidebar-character-model" style="">
                      </a>

                      <div class="profile-sidebar-info">
                        <div class="name">
                          <a href="/wow/en/character/some-server/sometoon/"
                          rel="np">Glitchshot</a>
                        </div>

                        <div class="under-name color-c8">
                          <span class="level"><strong>85</strong></span>
                          <a href="/wow/en/game/race/somerace" class="race">somerace</a> 
                          <a href="/wow/en/game/class/someclass" class="class">someclass</a>
                        </div>

                        <div class="guild">
                          <a href="/wow/en/guild/some-server/someguild/?character=sometoon">
                          Some Guild</a>
                        </div>

                        <div class="realm">
                          <span id="profile-info-realm" class="tip"
                          data-battlegroup="Stormstrike">Black
                          Dragonflight</span>
                        </div>
                      </div>
                    </div>

                    <ul class="profile-sidebar-menu" id="profile-sidebar-menu">
                      <li><a href=
                      "/wow/en/character/some-server/sometoon/" class=
                      "back-to" rel="np"><span class="arrow"><span class=
                      "icon">Character Summary</span></span></a></li>

                      <li class="root-menu"><a href=
                      "/wow/en/character/some-server/sometoon/achievement"
                         class="back-to" rel="np"><span class=
                         "arrow"><span class=
                         "icon">Achievements</span></span></a></li>

                      <li class=" active"><a href=
                      "/wow/en/character/some-server/sometoon/achievement#summary"
                         class="" rel="np"><span class="arrow"><span class=
                         "icon">Achievements</span></span></a></li>

                      <li class=""><a href=
                      "/wow/en/character/some-server/sometoon/achievement#92"
                         class="" rel="np"><span class="arrow"><span class=
                         "icon">General</span></span></a></li>

Я знаю, что разместил здесь много бесполезного кода, но хотел, чтобы вы, ребята, имели представление о том, как будет выглядеть DOM.

Из этого:

<a href="/wow/en/character/some-server/sometoon/achievement#92" class="" rel="np"><span class="arrow"><span class="icon">General</span></span></a>

Я хотел бы извлечь это:

/wow/en/character/some-server/sometoon/achievement#92

, который идет от последнего якоря в разметке.

Я прочитал столько, сколько я могу найти о том, как использовать запрос xpath для извлечения необходимой информации, но я явно что-то упускаю.Ниже приведен запрос, который, по моему мнению, должен работать, но не работает.

<?php
    $query = '*/ul[@class=profile-sidebar-menu]/ul/li[3]/ul/li[1]/a/@href';
    echo $query . "<br>";
    $achievementSubCategory = $xpath->query($query);

    $achiSubArray = array("URL" => $achievementSubCategory->item(0)->nodeValue);
    var_dump($achiSubArray);
    // Produces array(1) { ["URL"]=> NULL } which should look something more like:
    // array(1) { ["URL"]=> /wow/en/character/some-server/sometoon/achievement#92 }
?>

Заранее благодарю за помощь и советы

Ответы [ 3 ]

1 голос
/ 24 апреля 2011
*/ul[@class=profile-sidebar-menu]/ul/li[3]/ul/li[1]/a/@href

Есть несколько проблем с этим выражением XPath :

  1. Он ищет элемент ul, которыйявляется дочерней компанией текущего узла, которая имеет атрибут с именем class, строковое значение которого равно строковому значению одного из дочерних элементов ul с именем profile-sidebar-menu.Однако у ul нет дочерних элементов с именем profile-sidebar-menu, и целое выражение не выбирает ни одного узла.

  2. Другая проблема - это индексация.li[3] выбирает третий li элемент - дочерний элемент узла контекста.Однако требуемый элемент a является дочерним элементом четвертого li дочернего элемента контекстного узла.Это должно быть выражено как: li[4].Позиции XPath основаны на 1, а не на 0.

Если эти две проблемы исправлены, я считаю, что исправленное выражение должно выглядеть следующим образом :

*/ul[@class="profile-sidebar-menu"]/ul/li[4]/a/@href

Абсолютное выражение XPath, которое выбирает атрибут требуемого href, начиная с верхнего элемента body предоставленного XML-документа,:

/*/*/*/*/*/*/*/*/*/*/ul/li[4]/a/@href

Ниже приведен XML-документ(предоставленный, правильно сформированный добавлением нескольких отсутствующих конечных тегов:

<body class="en-us">
    <div id="wrapper">
        <div id="content">
            <div class="content-top">
                <div class="content-bot">
                    <div id="profile-wrapper" class=
              "profile-wrapper profile-wrapper-horde">
                        <div class="profile-sidebar-anchor">
                            <div class="profile-sidebar-outer">
                                <div class="profile-sidebar-inner">
                                    <div class="profile-sidebar-contents">
                                        <div class="profile-sidebar-crest">
                                            <a href="/wow/en/character/some-server/sometoon/" rel="np" class="profile-sidebar-character-model" style=""></a>
                                            <div class="profile-sidebar-info">
                                                <div class="name">
                                                    <a href="/wow/en/character/some-server/sometoon/"
                              rel="np">Glitchshot</a>
                                                </div>
                                                <div class="under-name color-c8">
                                                    <span class="level">
                                                        <strong>85</strong>
                                                    </span>
                                                    <a href="/wow/en/game/race/somerace" class="race">somerace</a>
                                                    <a href="/wow/en/game/class/someclass" class="class">someclass</a>
                                                </div>
                                                <div class="guild">
                                                    <a href="/wow/en/guild/some-server/someguild/?character=sometoon">
                              Some Guild</a>
                                                </div>
                                                <div class="realm">
                                                    <span id="profile-info-realm" class="tip"
                              data-battlegroup="Stormstrike">Black
                              Dragonflight</span>
                                                </div>
                                            </div>
                                        </div>
                                        <ul class="profile-sidebar-menu" id="profile-sidebar-menu">
                                            <li>
                                                <a href=
                          "/wow/en/character/some-server/sometoon/" class=
                          "back-to" rel="np">
                                                    <span class="arrow">
                                                        <span class=
                          "icon">Character Summary</span></span>
                                                </a>
                                            </li>
                                            <li class="root-menu">
                                                <a href=
                          "/wow/en/character/some-server/sometoon/achievement"
                             class="back-to" rel="np">
                                                    <span class=
                             "arrow">
                                                        <span class=
                             "icon">Achievements</span></span>
                                                </a>
                                            </li>
                                            <li class=" active">
                                                <a href=
                          "/wow/en/character/some-server/sometoon/achievement#summary"
                             class="" rel="np">
                                                    <span class="arrow">
                                                        <span class=
                             "icon">Achievements</span></span>
                                                </a>
                                            </li>
                                            <li class="">
                                                <a href=
                          "/wow/en/character/some-server/sometoon/achievement#92"
                             class="" rel="np">
                                                    <span class="arrow">
                                                        <span class=
                             "icon">General</span></span>
                                                </a>
                                            </li>
                                        </ul>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>

Можно проверить, что вышеприведенное абсолютное выражение XPath выбирает именно нужный атрибут href, оценивая его с помощьюинструмент, подобный визуализатору Xpath .

Вот снимок выбора, выполненного с помощью визуализатора XPath:

enter image description here

0 голосов
/ 24 апреля 2011

На основе html, показанного выше (и при условии, что окончательные теги правильно закрыты), выражение ewh'ов должно работать нормально.

Может быть, вы пропустили какую-то важную часть документа. Попробуйте быть более конкретным:

//ul[@class='profile-sidebar-menu' and @id='profile-sidebar-menu']/li/a[@href='/wow/en/character/some-server/sometoon/achievement#92']/@href

Я почти уверен, что это работает, протестировано онлайн с помощью XPath Query Expression Tool .

Если вы все еще не получили результаты, попробуйте показать все html, над которыми вы работаете.

0 голосов
/ 24 апреля 2011

Если ваша структура DOM непротиворечива, то должно работать что-то вроде следующего:

//ul[@class='profile-sidebar-menu']/li[last()]/a/@href

Ваше утверждение xpath не имеет смысла.У вас есть несколько ul в пути, но образец не структурирован таким образом.Кроме того, индексирование в xpath начинается с 1, а не с 0.

...