Определение того, начинается ли XML-элемент с «[CDATA[» использование XSLT

#xml #xslt

Вопрос:

У меня есть XSL, который я использую для визуализации RSS-каналов. Я хочу определить lt;descriptiongt; , начинается ли элемент элемента с lt;![CDATA[ — если да, то lt;descriptiongt; содержимое не должно отображаться. Если он не начинается с lt;![CDATA[ , то его можно визуализировать.

Но я, кажется, не могу подойти lt;![CDATA .

Вот пример RSS-канала:

 lt;?xml version="1.0" encoding="utf-8"?gt; lt;?xml-stylesheet type="text/xsl" href="pretty-feed.xsl"?gt; lt;rss version="2.0"gt;  lt;channelgt;  lt;titlegt;My Bloglt;/titlegt;  lt;linkgt;http://example.com/lt;/linkgt;  lt;descriptiongt;My Blog descriptionlt;/descriptiongt;  lt;itemgt;  lt;titlegt;My Blog Postlt;/titlegt;  lt;linkgt;http://example.com/2002/09/01/my-post/lt;/linkgt;  lt;descriptiongt;Content of the post.lt;/descriptiongt;  lt;/itemgt;  lt;/channelgt; lt;/rssgt;  

И вот часть моего pretty-feed.xsl файла, показывающая соответствующую часть:

 lt;xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"gt;  lt;xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes" /gt;  lt;xsl:template match="/"gt;  lt;html xmlns="http://www.w3.org/1999/xhtml"gt;  lt;headgt;  lt;bodygt;  lt;xsl:for-each select="/rss/channel/item"gt;  lt;xsl:if test="not(starts-with(normalize-space(description), 'amp;lt;![CDATA['))"gt;  lt;pgt;  lt;xsl:value-of select="description" /gt;  lt;/pgt;  lt;/xsl:ifgt;  lt;/xsl:for-eachgt;  lt;/bodygt;  lt;/htmlgt;  lt;/xsl:templategt; lt;/xsl:stylesheetgt;  

Это всегда делает то lt;descriptiongt; , с чего бы это ни начиналось. Итак, я предполагаю lt;![CDATA[ , что XSL не «видит» XSL как символы? Есть ли способ, которым я могу определить, существует он или нет?

Комментарии:

1. Нет, XSL не рассматривает его как эти символы, поскольку он является частью структуры XML. Насколько я знаю, XSL не может определить, есть ли там CDATA, поскольку текст извлекается заранее, и он предоставляется как есть всему, что хочет получить содержимое узла

2. Ах, как я и боялся. Все равно спасибо @SamiKuhmonen.

3. Какова реальная проблема, которую вы пытаетесь решить с помощью этого?

4. Некоторые древовидные модели, такие как DOM, позволяют различать узлы простого текста и узлы разделов CDATA, но XPath/XSLT работают с деревом XDM, в котором есть только текстовые узлы, независимо от лексической разметки.

5. @michael.hor257k Я надеялся придумать один .xls файл, который можно было бы использовать для визуализации каналов и отображения их lt;descriptiongt; , если он является открытым текстом, но не если он содержит CDATA (что часто указывает на то, что он содержит полный пост в блоге и т. Д.).

Ответ №1:

Ты не можешь. В модели XML-данных, используемой XSLT, CDATA рассматривается как не относящаяся к делу, скорее как пробелы между атрибутами в теге start. Элементы lt;zgt;amp;amp;amp;amp;amp;amp;lt;/zgt; и lt;zgt;lt;![CDATA[amp;amp;amp;]]gt;lt;/zgt; считаются на 100% эквивалентными; между ними нет различия, и оба просто имеют строковое значение «amp;amp;amp;».

Если в дизайне документа используются теги CDATA для передачи информации, то его необходимо переработать.