XPath

Поделись знанием:
Перейти к: навигация, поиск

XPath (XML Path Language) — язык запросов к элементам XML-документа. Разработан для организации доступа к частям документа XML в файлах трансформации XSLT и является стандартом консорциума W3C. XPath призван реализовать навигацию по DOM в XML. В XPath используется компактный синтаксис, отличный от принятого в XML. В 2007 году завершилась разработка версии 2.0, которая теперь является составной частью языка XQuery 1.0. В декабре 2009 года началась разработка версии 2.1, которая использует XQuery 1.1.

На данный момент самой популярной версией является XPath 1.0. Это связано с отсутствием поддержки XPath 2.0 со стороны открытых библиотек. В частности, речь идёт о LibXML, от которой зависит поддержка языка в браузерах, с одной стороны, и поддержка со стороны серверного интерпретатора, с другой.





Основы

XML имеет древовидную структуру. В документе всегда имеется корневой элемент (инструкция <?xml version="1.0"?> к дереву отношения не имеет). У элемента дерева всегда существуют потомки и предки, кроме корневого элемента, у которого предков нет, а также тупиковых элементов (листьев дерева), у которых нет потомков. Каждый элемент дерева находится на определенном уровне вложенности (далее — «уровень»). У элементов на одном уровне бывают предыдущие и следующие «братские» элементы, каждый из которых образует со своими потомками отдельный слой внутри уровня.

Это очень похоже на организацию каталогов в файловой системе, и строка XPath в логическом смысле — правила выбора пути к нужным «файлам» — элементам.

Физически же, на каждом шаге такого пути отбираются элементы, соответствующие условиям отбора на этом шаге, и в результате обращения по пути к документу получается множество элементов, удовлетворяющих данному пути.

Например, рассмотрим XHTML документ:

<html>
 <body>
    <div>Первый слой
      <span>блок текста в первом слое</span>
    </div>
    <div>Второй слой</div>
    <div>Третий слой
      <span class="text">первый блок в третьем слое</span>
      <span class="text">второй блок в третьем слое</span>
      <span>третий блок в третьем слое</span>
    </div>
    <span>четвёртый слой</span>
    <img />
 </body>
</html>

XPath-путь /html/body/*/span/@class (полный синтаксис имеет вид /child::html/child::body/child::*/child::span/attribute::class) будет соответствовать в нём двум элементам исходного документа — <span class="text">первый блок в третьем слое</span> и <span class="text">второй блок в третьем слое</span>.

Путь делится на шаги адресации, которые разделяются символом «косая черта» /. Каждый шаг адресации состоит из трех частей:

  • ось (в данном примере child::), это обязательная часть;
  • условие проверки узлов (в данном примере это проверки на соответствие элементов документа именам html, body, span, и символ *, который пропустит элемент с любым именем), также обязательная часть;
  • предикат (в данном примере attribute::class), необязательная часть, заключаемая в квадратные скобки, в которой могут содержаться дополнительные условия проверки элементов по другим осям, функции, операторы (+, -, <, > и пр.).

Анализ ведется слева направо. В текущем контексте выбираются элементы указанной в шаге оси, подходящие под указанные условия, и они образуют результат данного шага, который берётся как контекст для следующего шага. Контекст — это некая точка отсчета для осей, относительно которой рассчитывается результат шага адресации.

Если в начале пути не указан символ /, то корневой элемент документа уже на первом шаге будет назначен текущим контекстом, и ось child:: в этом контексте будет содержать его дочерние элементы. В данном примере ось child:: содержала бы один элемент body. Если первый символ пути — /, то путь адресации считается абсолютным (то есть от корня документа), и на первом шаге ось child:: содержит лишь сам корневой элемент. В данном примере child:: на первом шаге содержит элемент html.

Таким образом, первый шаг адресации /child::html явным образом делает текущим контекстом для следующего шага элемент html, что было бы и так сделано неявно, если этот шаг не был обозначен.

На втором шаге адресации (child::body) контекстом является элемент html. Ось child:: говорит о том, что необходимо найти всех непосредственных потомков элемента html, а условие проверки body говорит о том, что в формируемый набор элементов нужно включить все узлы с именем body. В ходе второго шага адресации получаем набор узлов, состоящий всего из одного элемента body, который и становится контекстом для третьего шага.

Третий шаг адресации: child::* . Ось child:: собирает всех непосредственных потомков элемента body, а условие проверки * говорит о том, что в формируемый набор нужно включить элементы основного типа с любым именем. В ходе этого шага получаем набор узлов, состоящий из трех элементов div, одного span и одного элемента img — итого, пять элементов.

Четвёртый шаг адресации: child::span/@class. Его контекстом является набор из пяти элементов, поэтому следующий набор узлов создается в пять проходов (за пять итераций). При первой итерации узлом контекста становится первый div. Согласно заданной оси child:: и правилу проверки span, в набор должны включаться непосредственные потомки этого div-а, имя которых равно span. Там такой один. При второй итерации в набор ничего добавляться не будет, так как у второго div нет потомков. Третья итерация увидит сразу три элемента span. Четвёртая ничего не увидит, так как у элемента span нет потомков span, а то что он сам span - не важно, ведь просматриваются именно потомки. Пятая тоже ничего не увидит, у элемента img тоже нет потомков span. Итак, в ходе проверки мог бы быть получен набор узлов, состоящий из четырёх элементов span. Это и было бы контекстом для последующей обработки, не будь на этом шаге указано предиката.

Но так как предикат на четвёртом шаге есть, по мере выполнения каждого из пяти проходов будет производиться дополнительная фильтрация отбираемых элементов. В данном случае у предиката ось attribute:: говорит о необходимости проверить, есть ли у отбираемого узла атрибуты, а условие class требует оставить лишь те узлы, у которых задан атрибут с именем class. И поэтому на первой итерации единственный найденный span фильтрацию предикатом не пройдёт, на третьей итерации фильтрацию пройдут два элемента из трёх, и в итоге, несмотря на то, что фильтрация происходит за пять итераций, в окончательный набор попадают только два элемента span.

Оси

Оси — это база языка XPath. Для некоторых осей существуют сокращённые обозначения.

  • ancestor:: — Возвращает множество предков.
  • ancestor-or-self:: — Возвращает множество предков и текущий элемент.
  • attribute:: — Возвращает множество атрибутов текущего элемента. Это обращение можно заменить на «@»
  • child:: — Возвращает множество потомков на один уровень ниже. Это название сокращается полностью, то есть его можно вовсе опускать.
  • descendant:: — Возвращает полное множество потомков (то есть, как ближайших потомков, так и всех их потомков).
  • descendant-or-self:: — Возвращает полное множество потомков и текущий элемент. Выражение «/descendant-or-self::node()/» можно сокращать до «//». С помощью этой оси, например, можно вторым шагом организовать отбор элементов с любого узла, а не только с корневого: достаточно первым шагом взять всех потомков корневого. Например, путь «//span» отберёт все узлы span документа, независимо от их положения в иерархии, взглянув как на имя корневого, так и на имена всех его дочерних элементов, на всю глубину их вложенности.
  • following:: — Возвращает множество элементов, расположенных ниже текущего элемента по дереву (на всех уровнях и слоях), исключая собственных потомков.
  • following-sibling:: — Возвращает множество братских элементов того же уровня, следующих за текущим слоев.
  • namespace:: — Возвращает множество, имеющее пространство имён (то есть присутствует атрибут xmlns).
  • parent:: — Возвращает предка на один уровень назад. Это обращение можно заменить на «..»
  • preceding:: — Возвращает множество элементов, расположенных выше текущего элемента по дереву (на всех уровнях и слоях), исключая множество собственных предков.
  • preceding-sibling:: — Возвращает множество братских элементов того же уровня, предшествующих текущему слоев.
  • self:: — Возвращает текущий элемент. Это обращение можно заменить на «.»

Условие проверки

Дополнением к базе является условие проверки. Условием проверки может быть либо прямое равенство конкретному имени, либо *, что пропустит любое имя, либо обращение к одной из функций, которые делятся на 5 групп:

Системные функции

  • node-set document(object, node-set?)
Возвращает документ, указанный в параметре object.
  • string format-number(number, string, string?)
Форматирует число согласно образцу, указанному во втором параметре, третий параметр указывает именованный формат числа, который должен быть учтён.
  • string generate-id(node-set?)
Возвращает строку, являющуюся уникальным идентификатором.
  • node-set key(string, object)
Возвращает множество с указанным ключом (аналогично функции id для идентификаторов).
  • string unparsed-entity-uri(string)
Возвращает непроанализированный URI, если такового нет, возвращает пустую строку.
  • boolean element-available(string)
Проверяет, доступен ли элемент или множество, указанное в параметре. Параметр рассматривается как XPath.
  • boolean function-available(string)
Проверяет, доступна ли функция, указанная в параметре. Параметр рассматривается как XPath.
  • object system-property(string)
Параметры, возвращающие системные переменные, могут быть:
* xsl: version — возвращает версию XSLT процессора.
* xsl: vendor — возвращает производителя XSLT процессора.
* xsl: vendor-url — возвращает URL, идентифицирующий производителя.
Если используется неизвестный параметр, функция возвращает пустую строку.
  • boolean lang(string)
Возвращает истину, если у текущего тега имеется атрибут xml: lang, либо родитель тега имеет атрибут xml: lang и в нем указан совпадающий строке символ.

Функции над множествами узлов

  • * — обозначает любое имя или набор символов по указанной оси, например: * — любой дочерний узел; @* — любой атрибут.
  • $name — обращение к переменной, где name — имя переменной или параметра.
  • [] — дополнительные условия выборки или, что то же самое, предикат шага адресации. Должен содержать логическое значение. Если содержит числовое, считается что это порядковый номер узла, что эквивалентно приписыванию перед этим числом выражения «position()=»
  • {} — если применяется внутри тега другого языка (например HTML), то XSLT процессор рассматривает содержимое фигурных скобок как XPath.
  • / — определяет уровень дерева, то есть разделяет шаги адресации
  • | — объединяет результат. То есть, можно написать несколько путей разбора через знак | и в результат такого выражения войдёт всё, что будет найдено любым из этих путей.
  • node-set node()
Возвращает все узлы. Вместо этой функции часто используют заменитель '*', но, в отличие от звездочки, функция node() возвращает и текстовые узлы.
  • string text()
Возвращает набор текстовых узлов;
  • node-set current()
Возвращает множество из одного элемента, который является текущим. Если мы делаем обработку множества с условиями, то единственным способом дотянуться из этого условия до текущего элемента будет данная функция.
  • number position()
Возвращает позицию элемента в множестве. Корректно работает только в цикле <xsl:for-each/>
  • number last()
Возвращает номер последнего элемента в множестве. Корректно работает только в цикле <xsl:for-each/>
  • number count(node-set)
Возвращает количество элементов в node-set.
  • string name(node-set?)
Возвращает полное имя первого тега в множестве.
  • string namespace-uri(node-set?)
Возвращает ссылку на url определяющий пространство имён.
  • string local-name(node-set?)
Возвращает имя первого тега в множестве, без пространства имён.
  • node-set id(object)
Находит элемент с уникальным идентификатором

Строковые функции

  • string string(object?)
Возвращает текстовое содержимое элемента. По сути возвращает объединенное множество текстовых элементов на один уровень ниже.
  • string concat(string, string, string*)
Объединяет две или более строк
  • number string-length(string?)
Возвращает длину строки.
  • boolean contains(string, string)
Возвращает истину, если первая строка содержит вторую, иначе возвращает ложь.
  • string substring(string, number, number?)
Возвращает строку вырезанную из строки начиная с указанного номера, и если указан второй номер — количество символов.
  • string substring-before(string, string)
Если найдена вторая строка в первой, возвращает строку до первого вхождения второй строки.
  • string substring-after(string, string)
Если найдена вторая строка в первой, возвращает строку после первого вхождения второй строки.
  • boolean starts-with(string, string)
Возвращает истину если вторая строка входит в начало первой, иначе возвращает ложь.
  • boolean ends-with(string, string)
Возвращает истину если вторая строка входит в конец первой, иначе возвращает ложь.
  • string normalize-space(string?)
Убирает лишние и повторные пробелы, а также управляющие символы, заменяя их пробелами.
  • string translate(string, string, string)
Заменяет символы первой строки, которые встречаются во второй строке, на соответствующие позиции символам из второй строки символы из третьей строки. translate(«bar», «abc», «ABC») вернет BAr.

Логические функции

Символ Значение
or логическое «или»
and логическое «и»
= логическое «равно»
< (&lt;) логическое «меньше»
> (&gt;) логическое «больше»
<= (&lt;=) логическое «меньше либо равно»
>= (&gt;=) логическое «больше либо равно»
  • boolean boolean(object)
Приводит объект к логическому типу;
  • boolean true()
Возвращает истину.
  • boolean false()
Возвращает ложь.
  • boolean not(boolean)
Отрицание, возвращает истину если аргумент ложь и наоборот.

Числовые функции

  • + — сложение
  • − — вычитание
  • * — умножение
  • div — обычное деление (не деление нацело!)
  • mod — остаток от деления
  • number number(object?)
Переводит объект в число.
  • number sum(node-set)
Вернёт сумму множества, каждый тег множества будет преобразован в строку и из него получено число.
  • number floor(number)
Возвращает наибольшее целое число, не большее, чем аргумент.
  • number ceiling(number)
Возвращает наименьшее целое число, не меньшее, чем аргумент.
  • number round(number)
Округляет число по математическим правилам.

Напишите отзыв о статье "XPath"

Ссылки

  • [www.w3.org/TR/xpath XPath 1.0. Рекомендация W3C.]  (англ.)
  • [www.w3.org/TR/xpath20 XPath 2.0. Рекомендация W3C.]  (англ.)
  • [www.w3.org/TR/xpath-21 XPath 2.1. Рекомендация W3C.]  (англ.)
  • [www.citforum.ru/internet/xpath/index.shtml XPath 1.0. Перевод рекомендации W3C на русский язык.]
  • [www.zvon.org/xxl/XPathTutorial/General_rus/examples.html XPath в примерах]
  • [www.xakep.ru/post/44160/default.asp XPath инъекции]
  • [www.quizful.net/post/xpath-in-javascript XPath в JavaScript]


К:Википедия:Статьи без источников (тип: не указан)

Отрывок, характеризующий XPath

– Да, я с вами, – сказал Пьер, глядя вокруг себя и отыскивая глазами своего берейтора. Тут только в первый раз Пьер увидал раненых, бредущих пешком и несомых на носилках. На том самом лужке с пахучими рядами сена, по которому он проезжал вчера, поперек рядов, неловко подвернув голову, неподвижно лежал один солдат с свалившимся кивером. – А этого отчего не подняли? – начал было Пьер; но, увидав строгое лицо адъютанта, оглянувшегося в ту же сторону, он замолчал.
Пьер не нашел своего берейтора и вместе с адъютантом низом поехал по лощине к кургану Раевского. Лошадь Пьера отставала от адъютанта и равномерно встряхивала его.
– Вы, видно, не привыкли верхом ездить, граф? – спросил адъютант.
– Нет, ничего, но что то она прыгает очень, – с недоуменьем сказал Пьер.
– Ээ!.. да она ранена, – сказал адъютант, – правая передняя, выше колена. Пуля, должно быть. Поздравляю, граф, – сказал он, – le bapteme de feu [крещение огнем].
Проехав в дыму по шестому корпусу, позади артиллерии, которая, выдвинутая вперед, стреляла, оглушая своими выстрелами, они приехали к небольшому лесу. В лесу было прохладно, тихо и пахло осенью. Пьер и адъютант слезли с лошадей и пешком вошли на гору.
– Здесь генерал? – спросил адъютант, подходя к кургану.
– Сейчас были, поехали сюда, – указывая вправо, отвечали ему.
Адъютант оглянулся на Пьера, как бы не зная, что ему теперь с ним делать.
– Не беспокойтесь, – сказал Пьер. – Я пойду на курган, можно?
– Да пойдите, оттуда все видно и не так опасно. А я заеду за вами.
Пьер пошел на батарею, и адъютант поехал дальше. Больше они не видались, и уже гораздо после Пьер узнал, что этому адъютанту в этот день оторвало руку.
Курган, на который вошел Пьер, был то знаменитое (потом известное у русских под именем курганной батареи, или батареи Раевского, а у французов под именем la grande redoute, la fatale redoute, la redoute du centre [большого редута, рокового редута, центрального редута] место, вокруг которого положены десятки тысяч людей и которое французы считали важнейшим пунктом позиции.
Редут этот состоял из кургана, на котором с трех сторон были выкопаны канавы. В окопанном канавами место стояли десять стрелявших пушек, высунутых в отверстие валов.
В линию с курганом стояли с обеих сторон пушки, тоже беспрестанно стрелявшие. Немного позади пушек стояли пехотные войска. Входя на этот курган, Пьер никак не думал, что это окопанное небольшими канавами место, на котором стояло и стреляло несколько пушек, было самое важное место в сражении.
Пьеру, напротив, казалось, что это место (именно потому, что он находился на нем) было одно из самых незначительных мест сражения.
Войдя на курган, Пьер сел в конце канавы, окружающей батарею, и с бессознательно радостной улыбкой смотрел на то, что делалось вокруг него. Изредка Пьер все с той же улыбкой вставал и, стараясь не помешать солдатам, заряжавшим и накатывавшим орудия, беспрестанно пробегавшим мимо него с сумками и зарядами, прохаживался по батарее. Пушки с этой батареи беспрестанно одна за другой стреляли, оглушая своими звуками и застилая всю окрестность пороховым дымом.
В противность той жуткости, которая чувствовалась между пехотными солдатами прикрытия, здесь, на батарее, где небольшое количество людей, занятых делом, бело ограничено, отделено от других канавой, – здесь чувствовалось одинаковое и общее всем, как бы семейное оживление.
Появление невоенной фигуры Пьера в белой шляпе сначала неприятно поразило этих людей. Солдаты, проходя мимо его, удивленно и даже испуганно косились на его фигуру. Старший артиллерийский офицер, высокий, с длинными ногами, рябой человек, как будто для того, чтобы посмотреть на действие крайнего орудия, подошел к Пьеру и любопытно посмотрел на него.
Молоденький круглолицый офицерик, еще совершенный ребенок, очевидно, только что выпущенный из корпуса, распоряжаясь весьма старательно порученными ему двумя пушками, строго обратился к Пьеру.
– Господин, позвольте вас попросить с дороги, – сказал он ему, – здесь нельзя.
Солдаты неодобрительно покачивали головами, глядя на Пьера. Но когда все убедились, что этот человек в белой шляпе не только не делал ничего дурного, но или смирно сидел на откосе вала, или с робкой улыбкой, учтиво сторонясь перед солдатами, прохаживался по батарее под выстрелами так же спокойно, как по бульвару, тогда понемногу чувство недоброжелательного недоуменья к нему стало переходить в ласковое и шутливое участие, подобное тому, которое солдаты имеют к своим животным: собакам, петухам, козлам и вообще животным, живущим при воинских командах. Солдаты эти сейчас же мысленно приняли Пьера в свою семью, присвоили себе и дали ему прозвище. «Наш барин» прозвали его и про него ласково смеялись между собой.
Одно ядро взрыло землю в двух шагах от Пьера. Он, обчищая взбрызнутую ядром землю с платья, с улыбкой оглянулся вокруг себя.
– И как это вы не боитесь, барин, право! – обратился к Пьеру краснорожий широкий солдат, оскаливая крепкие белые зубы.
– А ты разве боишься? – спросил Пьер.
– А то как же? – отвечал солдат. – Ведь она не помилует. Она шмякнет, так кишки вон. Нельзя не бояться, – сказал он, смеясь.
Несколько солдат с веселыми и ласковыми лицами остановились подле Пьера. Они как будто не ожидали того, чтобы он говорил, как все, и это открытие обрадовало их.
– Наше дело солдатское. А вот барин, так удивительно. Вот так барин!
– По местам! – крикнул молоденький офицер на собравшихся вокруг Пьера солдат. Молоденький офицер этот, видимо, исполнял свою должность в первый или во второй раз и потому с особенной отчетливостью и форменностью обращался и с солдатами и с начальником.
Перекатная пальба пушек и ружей усиливалась по всему полю, в особенности влево, там, где были флеши Багратиона, но из за дыма выстрелов с того места, где был Пьер, нельзя было почти ничего видеть. Притом, наблюдения за тем, как бы семейным (отделенным от всех других) кружком людей, находившихся на батарее, поглощали все внимание Пьера. Первое его бессознательно радостное возбуждение, произведенное видом и звуками поля сражения, заменилось теперь, в особенности после вида этого одиноко лежащего солдата на лугу, другим чувством. Сидя теперь на откосе канавы, он наблюдал окружавшие его лица.
К десяти часам уже человек двадцать унесли с батареи; два орудия были разбиты, чаще и чаще на батарею попадали снаряды и залетали, жужжа и свистя, дальние пули. Но люди, бывшие на батарее, как будто не замечали этого; со всех сторон слышался веселый говор и шутки.
– Чиненка! – кричал солдат на приближающуюся, летевшую со свистом гранату. – Не сюда! К пехотным! – с хохотом прибавлял другой, заметив, что граната перелетела и попала в ряды прикрытия.
– Что, знакомая? – смеялся другой солдат на присевшего мужика под пролетевшим ядром.
Несколько солдат собрались у вала, разглядывая то, что делалось впереди.
– И цепь сняли, видишь, назад прошли, – говорили они, указывая через вал.
– Свое дело гляди, – крикнул на них старый унтер офицер. – Назад прошли, значит, назади дело есть. – И унтер офицер, взяв за плечо одного из солдат, толкнул его коленкой. Послышался хохот.
– К пятому орудию накатывай! – кричали с одной стороны.
– Разом, дружнее, по бурлацки, – слышались веселые крики переменявших пушку.
– Ай, нашему барину чуть шляпку не сбила, – показывая зубы, смеялся на Пьера краснорожий шутник. – Эх, нескладная, – укоризненно прибавил он на ядро, попавшее в колесо и ногу человека.
– Ну вы, лисицы! – смеялся другой на изгибающихся ополченцев, входивших на батарею за раненым.
– Аль не вкусна каша? Ах, вороны, заколянились! – кричали на ополченцев, замявшихся перед солдатом с оторванной ногой.
– Тое кое, малый, – передразнивали мужиков. – Страсть не любят.
Пьер замечал, как после каждого попавшего ядра, после каждой потери все более и более разгоралось общее оживление.
Как из придвигающейся грозовой тучи, чаще и чаще, светлее и светлее вспыхивали на лицах всех этих людей (как бы в отпор совершающегося) молнии скрытого, разгорающегося огня.
Пьер не смотрел вперед на поле сражения и не интересовался знать о том, что там делалось: он весь был поглощен в созерцание этого, все более и более разгорающегося огня, который точно так же (он чувствовал) разгорался и в его душе.
В десять часов пехотные солдаты, бывшие впереди батареи в кустах и по речке Каменке, отступили. С батареи видно было, как они пробегали назад мимо нее, неся на ружьях раненых. Какой то генерал со свитой вошел на курган и, поговорив с полковником, сердито посмотрев на Пьера, сошел опять вниз, приказав прикрытию пехоты, стоявшему позади батареи, лечь, чтобы менее подвергаться выстрелам. Вслед за этим в рядах пехоты, правее батареи, послышался барабан, командные крики, и с батареи видно было, как ряды пехоты двинулись вперед.
Пьер смотрел через вал. Одно лицо особенно бросилось ему в глаза. Это был офицер, который с бледным молодым лицом шел задом, неся опущенную шпагу, и беспокойно оглядывался.
Ряды пехотных солдат скрылись в дыму, послышался их протяжный крик и частая стрельба ружей. Через несколько минут толпы раненых и носилок прошли оттуда. На батарею еще чаще стали попадать снаряды. Несколько человек лежали неубранные. Около пушек хлопотливее и оживленнее двигались солдаты. Никто уже не обращал внимания на Пьера. Раза два на него сердито крикнули за то, что он был на дороге. Старший офицер, с нахмуренным лицом, большими, быстрыми шагами переходил от одного орудия к другому. Молоденький офицерик, еще больше разрумянившись, еще старательнее командовал солдатами. Солдаты подавали заряды, поворачивались, заряжали и делали свое дело с напряженным щегольством. Они на ходу подпрыгивали, как на пружинах.
Грозовая туча надвинулась, и ярко во всех лицах горел тот огонь, за разгоранием которого следил Пьер. Он стоял подле старшего офицера. Молоденький офицерик подбежал, с рукой к киверу, к старшему.
– Имею честь доложить, господин полковник, зарядов имеется только восемь, прикажете ли продолжать огонь? – спросил он.
– Картечь! – не отвечая, крикнул старший офицер, смотревший через вал.
Вдруг что то случилось; офицерик ахнул и, свернувшись, сел на землю, как на лету подстреленная птица. Все сделалось странно, неясно и пасмурно в глазах Пьера.
Одно за другим свистели ядра и бились в бруствер, в солдат, в пушки. Пьер, прежде не слыхавший этих звуков, теперь только слышал одни эти звуки. Сбоку батареи, справа, с криком «ура» бежали солдаты не вперед, а назад, как показалось Пьеру.
Ядро ударило в самый край вала, перед которым стоял Пьер, ссыпало землю, и в глазах его мелькнул черный мячик, и в то же мгновенье шлепнуло во что то. Ополченцы, вошедшие было на батарею, побежали назад.
– Все картечью! – кричал офицер.
Унтер офицер подбежал к старшему офицеру и испуганным шепотом (как за обедом докладывает дворецкий хозяину, что нет больше требуемого вина) сказал, что зарядов больше не было.
– Разбойники, что делают! – закричал офицер, оборачиваясь к Пьеру. Лицо старшего офицера было красно и потно, нахмуренные глаза блестели. – Беги к резервам, приводи ящики! – крикнул он, сердито обходя взглядом Пьера и обращаясь к своему солдату.
– Я пойду, – сказал Пьер. Офицер, не отвечая ему, большими шагами пошел в другую сторону.
– Не стрелять… Выжидай! – кричал он.
Солдат, которому приказано было идти за зарядами, столкнулся с Пьером.
– Эх, барин, не место тебе тут, – сказал он и побежал вниз. Пьер побежал за солдатом, обходя то место, на котором сидел молоденький офицерик.
Одно, другое, третье ядро пролетало над ним, ударялось впереди, с боков, сзади. Пьер сбежал вниз. «Куда я?» – вдруг вспомнил он, уже подбегая к зеленым ящикам. Он остановился в нерешительности, идти ему назад или вперед. Вдруг страшный толчок откинул его назад, на землю. В то же мгновенье блеск большого огня осветил его, и в то же мгновенье раздался оглушающий, зазвеневший в ушах гром, треск и свист.
Пьер, очнувшись, сидел на заду, опираясь руками о землю; ящика, около которого он был, не было; только валялись зеленые обожженные доски и тряпки на выжженной траве, и лошадь, трепля обломками оглобель, проскакала от него, а другая, так же как и сам Пьер, лежала на земле и пронзительно, протяжно визжала.


Пьер, не помня себя от страха, вскочил и побежал назад на батарею, как на единственное убежище от всех ужасов, окружавших его.
В то время как Пьер входил в окоп, он заметил, что на батарее выстрелов не слышно было, но какие то люди что то делали там. Пьер не успел понять того, какие это были люди. Он увидел старшего полковника, задом к нему лежащего на валу, как будто рассматривающего что то внизу, и видел одного, замеченного им, солдата, который, прорываясь вперед от людей, державших его за руку, кричал: «Братцы!» – и видел еще что то странное.
Но он не успел еще сообразить того, что полковник был убит, что кричавший «братцы!» был пленный, что в глазах его был заколон штыком в спину другой солдат. Едва он вбежал в окоп, как худощавый, желтый, с потным лицом человек в синем мундире, со шпагой в руке, набежал на него, крича что то. Пьер, инстинктивно обороняясь от толчка, так как они, не видав, разбежались друг против друга, выставил руки и схватил этого человека (это был французский офицер) одной рукой за плечо, другой за гордо. Офицер, выпустив шпагу, схватил Пьера за шиворот.