#xml #xslt #xpath
#xml #xslt #xpath
Вопрос:
Хорошо, у меня есть структура помощи в поиске, подобная этой:
<c01 level="file">
<c02 level="file"></c02>
</c01>
Для моего шаблона XSLT я хотел бы иметь возможность сопоставлять только узлы с атрибутом level =»file», у которых родительский элемент также имеет атрибут level = «file», чтобы я мог применить некоторое конкретное форматирование к дочернему элементу.
Обычно для сопоставления level =»file» я просто использую следующее:
<xsl:template match="*[@level="file"]">
Однако для целей форматирования (отступ и т.д.) Мне нужно, чтобы узел, который является дочерним элементом узла с тем же атрибутом, обрабатывался иначе, чем его родительский элемент. Итак, что-то вроде:
<xsl:template match="*[@level="file"] and parent::[@level="file"]">
Есть идеи? Я надеюсь, что это имеет смысл. Спасибо!
Ответ №1:
Использовать:
<xsl:template match="*[@level='file' ]/*[@level='file']">
Этот шаблон сопоставляет любой элемент, строковое значение level
атрибута которого равно "file"
, и который является дочерним элементом элемента, строковое значение level
атрибута которого равно "file"
Обратите внимание: не используется ..
ось parent::
или //
, и это, вероятно, самый простой и точный шаблон сопоставления.
Комментарии:
1. Как вы думаете, этот фрагмент будет отменять совпадения на
*[@level='file' ]
? Это проблема, с которой я сейчас сталкиваюсь. Получение этой строки для воздействия на узлы, как*[@level='file' ]/*[@level='file']/did
когда у меня уже есть*[@level='file' ]/did
в таблице стилей.2. @librarion: Да, этот шаблон сопоставления более специфичен. Если он не выбран, то укажите
priority="3"
Ответ №2:
Сопоставить на любом узле, родительский элемент которого имеет тот же атрибут @level, что и у меня, и мой атрибут @level = ‘file’
<xsl:template match="*[../@level=./@level][./@level='file']">
...
</xsl:template>
Комментарии:
1. Работает ли это, если у меня уже есть другой раздел, соответствующий родительскому с
<xsl:template match="*[@level="file"]">
? Или они будут конфликтовать?2. Насколько я понимаю, выигрывает более конкретное совпадение — у меня бы не было под рукой моей книги Майкла Кея по XSLT, но я помню, что есть взвешивание, которое применяется для определения порядка совпадений.
3. Хорошо, это имеет смысл. Последнее: что, если у меня есть дочерние элементы под ним? Как и в, могу ли я затем продолжить сопоставление
<xsl:template match="*[../@level=./@level][./@level='file']/scopecontent">
, или это приведет к панике?4. какой узел вы хотите, чтобы он соответствовал вашему узлу? scopecontent или это родительский элемент? Вам нужно рассматривать совпадение как путь с [filter] — таким образом, часть пути соответствует выбору узлов, например, ‘foo’ — все узлы вызывают foo, и фильтр [ @attribute = ‘bar’ ][baz] — которые имеют атрибут bar и дочерний узел baz. — итак, в вашем примере вы соответствуете узлу «содержимое области», который находится на единицу ниже любого узла, который соответствует вашим предыдущим критериям.