Это преобразование :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
Abstract: <xsl:text/>
<xsl:for-each select="*/MT[starts-with(@N, 'Abstract')]">
<xsl:value-of select="@V"/>
</xsl:for-each>
Author: <xsl:text/>
<xsl:for-each select="*/MT[starts-with(@N, 'Author')]">
<xsl:value-of select="@V"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
при применении к предоставленному документу XML:
<R N="14" MIME="application/pdf">
<RK>7</RK>
<MT N="Abstract" V="Lorem Ipsum is simply dummy text of the printing " />
<MT N="Abstract1" V="and typesetting industry. Lorem Ipsum has been the industry's standard " />
<MT N="Author" V="Bernard Shaw;" />
<MT N="Author1" V="Mark Twain" />
<MT N="Abstract2" V="dummy text ever since the 1500s, when an unknown printer took a galley" />
<LANG>en</LANG>
</R>
создает искомыйрезультат:
Abstract: Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley
Author: Bernard Shaw;Mark Twain
Дальнейший рефакторинг :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
Abstract: <xsl:text/>
<xsl:call-template name="concatAttributes"/>
Author: <xsl:text/>
<xsl:call-template name="concatAttributes">
<xsl:with-param name="pKeyStartString" select="'Author'"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="concatAttributes">
<xsl:param name="pKeyAttribName" select="'N'"/>
<xsl:param name="pKeyStartString" select="'Abstract'"/>
<xsl:param name="pValueAttribName" select="'V'"/>
<xsl:for-each select=
"*/MT[starts-with(@*[name()=$pKeyAttribName], $pKeyStartString)]">
<xsl:value-of select="@*[name()=$pValueAttribName]"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Второй рефакторинг (запрошенный ОП):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vAbstract">
<xsl:apply-templates mode="retrieve" select="//MT"/>
</xsl:variable>
<xsl:variable name="vAuthors">
<xsl:apply-templates mode="retrieve" select="//MT">
<xsl:with-param name="pKeyStartString" select="'Author'"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:template match="/">
Abstract: <xsl:value-of select="$vAbstract"/>
Authors:: <xsl:value-of select="$vAuthors"/>
</xsl:template>
<xsl:template match="MT" mode="retrieve">
<xsl:param name="pKeyAttribName" select="'N'"/>
<xsl:param name="pKeyStartString" select="'Abstract'"/>
<xsl:param name="pValueAttribName" select="'V'"/>
<xsl:if test="starts-with(@*[name()=$pKeyAttribName], $pKeyStartString)">
<xsl:value-of select="@*[name()=$pValueAttribName]"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
РЕДАКТИРОВАТЬ : ОП запросил, чтобы "вся обработка выполнялась в шаблоне, соответствующем MT
".Хотя это возможно в простых случаях (см. Ответ @ Alejandro), выполнение всей обработки в одном шаблоне, соответствующем MT
, открывает большие промежутки неизвестных.Например, может потребоваться обработать другие MT
элементы другим способом, и в этом случае такая обработка вообще не будет выполняться.
В более сложных случаях (например, когда приходят элементы и атрибуты)в любом порядке, но выходные данные должны быть отсортированы (Abstract1, Abstract2, ..., Abstract-N), тогда сортировка должна быть указана явно, и это должно быть вне шаблона, соответствующего MT
. Поэтому, в общем случае, невозможно получить требуемый вывод с кодом только в пределах сопоставления шаблона MT
.
Я бы порекомендовал сопоставление одного шаблонаMT
находиться в именованном режиме и что его следует использовать в "стиле стиля" - применяется явно вызывающим абонентом.