2012-02-13 2 views
6

Как использовать шаблон-шаблон для выбора только тех элементов по имени (не значение), которые заканчиваются определенным шаблоном? Предположим, что следующий XML ...Как выбрать элементы по части их имени в XSL/XPath?

<report> 
    <report_item> 
    <report_created_on/> 
    <report_cross_ref/> 
    <monthly_adj/> 
    <quarterly_adj/> 
    <ytd_adj/> 
    </report_item> 
    <report_item> 
    .... 
    </report_item> 
</report> 

Я хочу использовать <xsl:apply-templates> на всех экземплярах <report_item>, где потомок элементы заканчиваются «adj`, так, в этом случае, только monthly_adj, quaterly_adj и ytd_adj будут выбраны и применяется с шаблоном.

<xsl:template match="report"> 
    <xsl:apply-templates select="report_item/(elements ending with 'adj')"/> 
</xsl:template> 

ответ

10

Я не думаю, что синтаксис регулярного выражения доступен в этом контексте, даже в XSLT 2.0. Но в этом случае вам это не нужно.

<xsl:apply-templates select="report_item/*[ends-with(name(), 'adj')]"/> 

* соответствует любому узлу

[pred] выполняет тест узла против селектора (в данном случае *) (где pred предикат оценивается в контексте выбранного узла)

name() возвращается имя тега элемента (для этой цели должно быть эквивалентно local-name).

ends-with() - встроенная функция строки XPath.

+0

NEW STACKOVERFLOW WORLD RECORD .... Самый быстрый ответ Когда-либо, LOL, вы правы, а не регулярное выражение, просто простых «концов с» было достаточно, спасибо. – raffian

+0

Рад помочь :) Я обновил название, чтобы лучше совместить вопрос. – harpo

+0

Да, я планировал обновить себя, еще раз спасибо! – raffian

2

Слегка аккуратнее решение (XSLT 2.0+ только):

<xsl:apply-templates select="report_item/*[matches(name(),'adj$')]"/> 

Вот самопроверки, чтобы доказать, что он работает. (Протестировано на саксонском языке).

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:fn="http://www.w3.org/2005/xpath-functions" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema" 
       exclude-result-prefixes="xs fn"> 
<xsl:output method="xml" indent="yes" encoding="utf-8" /> 
<xsl:variable name="report-data"> 
    <report> 
    <report_item> 
    <report_created_on/> 
    <report_cross_ref/> 
    <monthly_adj>Jan</monthly_adj> 
    <quarterly_adj>Q1</quarterly_adj> 
    <ytd_adj>2012</ytd_adj> 
    </report_item> 
    </report> 
</xsl:variable> 
<xsl:template match="/" name="main"> 
    <reports-ending-with-adj> 
    <xsl:element name="using-regex"> 
    <xsl:apply-templates select="$report-data//report_item/*[fn:matches(name(),'adj$')]"/> 
    </xsl:element> 
    <xsl:element name="using-ends-with-function"> 
    <xsl:apply-templates select="$report-data//report_item/*[fn:ends-with(name(), 'adj')]"/> 
    </xsl:element> 
    </reports-ending-with-adj> 
</xsl:template> 
</xsl:stylesheet> 
+0

«Матч» работал для меня. Но у меня есть проблема: http://xsltransform.net/pPzifp5/3 (я бы хотел, чтобы 'mOrder' сказал, какой' li' я хотел бы отображать первый, второй, третий ...) Спасибо. – Si8

+0

Или что-то вроде этого: http://xsltransform.net/pPzifp5/4 (Я ищу для отображения родительского LI и sub LI, но он умножается для каждой итерации и дублирования. Пустое LI я бы хотел не показывать и только показать, есть ли у него текст.) Спасибо за помощь – Si8

+0

Задать вопрос, и на него будет дан ответ. –

Смежные вопросы