#xslt
#xslt
Вопрос:
У меня есть XML-документ в формате follwoing:
<xml>
<dtd name="formslst">
<XMLDOC>
<formslst>
<forms>
<h1>
Level 1 heading
<h2>
level 2 heading
<h3>
level 3 heading
<file>
file1.pdf
<title>
title of file 1
<file>
file2.pdf
<title>
title of file2
<h3> level 3 internal heading
<file> file2.pdf
<title>
title of file 3
</title>
</file>
</h3>
</title>
</file>
</title>
</file>
</h3>
</h2>
</h1>
</forms>
</formslst>
</XMLDOC>
Мне нужен скрипт xslt, чтобы, если я передам параметр как «file2.pdf», он должен вернуть мне заголовок file2.pdf как «заголовок file2» и предыдущий текст h3 «заголовок уровня 3«, h2 «заголовок уровня 2» и h1 «заголовок уровня 1″значения.
Но если я передам файл file3.pdf, он должен вернуть мне заголовок file3.pdf как «заголовок файла 3» и предшествующие текстовые значения h3 «внутренний заголовок уровня 3«, h2 «заголовок уровня 2» и h1 «заголовок уровня 1».
Ответ №1:
Вы можете сопоставить соответствующий файл, выполнив следующее (где $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 возвращается следующее (обратите внимание, что в вашем XML есть два file2.pdf, я предполагаю, что вторым должен быть 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>