Мои ответы очень похожи на ответы @ Flack :
Наличие этого XML-документа (исправление предоставленного документа при закрытии множества незамеченных <br>
s и оборачивании всего в один верхний элемент):
<body>
<p class="titlestyle">ANT101H5 Introduction to Biological Anthropology and Archaeology
<span class='distribution'>(SCI)</span>
</p>
<span class='normaltext'> Anthropology is the global and holistic study of human biology and behaviour, and includes four subfields: biological anthropology, archaeology, sociocultural anthropology and linguistics. The material covered is directed to answering the question: What makes us human? This course is a survey of biological anthropology and archaeology. [
<span class='Helpcourse' onMouseover="showtip(this,event,'24 Lectures')" onMouseout="hidetip()">24L</span>,
<span class='Helpcourse' onMouseover="showtip(this,event,'12 Tutorials')" onMouseout="hidetip()">12T</span>]
<br/>
<span class='title2'>Exclusion: </span>
<a href='javascript:OpenCourse("WEBCOURSENOTFOUND.html")'>ANT100Y5</a>
<br/>
<span class='title2'>Prerequisite: </span>
<a href='javascript:OpenCourse("WEBCOURSEANT102H5.pl?fv=1")'>ANT102H5</a>
<br/>
</span>
<br/>
<br/>
<br/>
</body>
Это выражение XPath :
normalize-space(/*/p/text()[1])
когда вычисляется, получается искомая строка (окружающие кавычки не в результате. Я добавил их, чтобы показать точную полученную строку):
"ANT101H5 Introduction to Biological Anthropology and Archaeology"
Это выражение XPath :
concat((//span[@class='title2'])[1],
(//span[@class='title2'])[1]
/following-sibling::a[1]
)
при оценке дает следующий желаемый результат:
"Exclusion: ANT100Y5"
Это выражение XPath :
concat((//span[@class='title2'])[2],
(//span[@class='title2'])[2]
/following-sibling::a[1]
)
при оценке дает следующий желаемый результат:
"Prerequisite: ANT102H5"
Примечание : в данном конкретном случае аббревиатура //
не требуется, и на самом деле эту аббревиатуру следует всегда, когда это возможно, избегать, поскольку она приводит к более медленной оценке выражения, что во многих случаях полный (под) обход дерева. Я намеренно использую «//», потому что предоставленный фрагмент XML не дает нам полной структуры документа XML. Также это демонстрирует, как правильно индексировать результаты использования //
(обратите внимание на окружающие скобки) - помогая предотвратить очень частую ошибку при попытке сделать это
ОБНОВЛЕНИЕ : ОП запросил одно выражение XPath, которое выбирает все необходимые текстовые узлы - вот оно:
/*/p/text()[1]
|
(//span[@class='title2'])[1]/text()
|
(//span[@class='title2'])[1]/following-sibling::a[1]/text()
|
(//span[@class='title2'])[2]/text()
|
(//span[@class='title2'])[2]/following-sibling::a[1]/text()
При применении к тому же XML-документу, что и выше, конкатенация текстовых узлов - это именно то, что требуется:
ANT101H5 Introduction to Biological Anthropology and Archaeology
Exclusion: ANT100Y5Prerequisite: ANT102H5
Этот результат можно подтвердить, выполнив следующее преобразование XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:copy-of select=
"/*/p/text()[1]
|
(//span[@class='title2'])[1]/text()
|
(//span[@class='title2'])[1]/following-sibling::a[1]/text()
|
(//span[@class='title2'])[2]/text()
|
(//span[@class='title2'])[2]/following-sibling::a[1]/text()
"/>
</xsl:template>
</xsl:stylesheet>
когда это преобразование применяется к тому же XML-документу (указанному ранее в этом ответе), получается требуемый, правильный результат :
ANT101H5 Introduction to Biological Anthropology and Archaeology
Exclusion: ANT100Y5Prerequisite: ANT102H5
Наконец : следующее единственное выражение XPath выбирает ровно все требуемые текстовые узлы на странице HTML с предоставленной ссылкой (после того, как она убрана, чтобы стать правильно сформированным XML):
(//p[@class='titlestyle'])[2]/text()[1]
|
(//span[@class='title2'])[2]/text()
|
(//span[@class='title2'])[2]/following-sibling::a[1]/text()
|
(//span[@class='title2'])[3]/text()
|
(//span[@class='title2'])[3]/following-sibling::a[1]/text()