Вы можете сопоставить соответствующий файл, выполнив следующее (где $ file - это параметр, содержащий имя вашего файла)
<xsl:apply-templates select="//file[normalize-space(text()) = $file]"/>
Как только файл сопоставлен, заголовок получаетсядовольно просто
<xsl:value-of select="normalize-space(title/text())" />
Посмотрев на структуру xml (которая не является правильной, потому что вам не хватает закрывающих тегов dtd и xml ), вына самом деле не нужны предыдущие элементы h , но предки
<xsl:apply-templates select="ancestor::h1|ancestor::h2|ancestor::h3">
Вот полный XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="file" select="'file2.pdf'"/>
<xsl:template match="/">
<xsl:apply-templates select="//file[normalize-space(text()) = $file]"/>
</xsl:template>
<xsl:template match="file">
<title>
<xsl:value-of select="normalize-space(title/text())"/>
</title>
<xsl:apply-templates select="ancestor::h1|ancestor::h2|ancestor::h3">
<xsl:sort select="position()" order="descending"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="h1|h2|h3">
<xsl:copy>
<xsl:value-of select="normalize-space(text())"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Применительно к вашему примеру XML, следующеевозвращается (обратите внимание, у вас есть два file2.pdf в вашем XML, я предполагаю, что второе должно быть file3.pdf
<title>title of file2</title>
<h3>level 3 heading</h3>
<h2>level 2 heading</h2>
<h1>Level 1 heading</h1>
Когда параметр изменяетсяв file3.pdf вывод выглядит следующим образом:
<title>title of file 3</title>
<h3>level 3 internal heading</h3>
<h3>level 3 heading</h3>
<h2>level 2 heading</h2>
<h1>Level 1 heading</h1>