Как получить CDATA из xml-узла с помощью xsl?
Я пытаюсь получить CDATA
содержимое XML-узла с помощью XSL. Этот
узел в настоящее время выглядит так:
<node id="1" text="Book Information" ><![CDATA[This is sample text]]></node>
мне нужно This is sample text
кусок. Кто-нибудь знает об этом?
спасибо заранее.
5 ответов
Ну, если я использую эту таблицу стилей:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="node/text()">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
в этом XML-файле:
<?xml version="1.0" encoding="utf-8"?>
<node id=1 text="Book Information" ><![CDATA[This is sample text]]></node>
Я получаю ошибку разбора, потому что id=1
является недопустимым XML.
размещение кавычек вокруг значения атрибута (id="1"
) и повторный запуск таблицы стилей, я получаю в качестве вывода:
это образец текста
итак, есть начало. В принципе, просто рассматривайте CDATA как текстовый узел, и вы на своем пути.
вы сказал:
Я нашел что-то вроде:
<xsl:output cdata-section-elements="text"/>
и затем, чтобы принести CDATA:<xsl:value-of select="node" />
этот подход отлично работает, если вы используете value-of
как хорошо. Вот пример вдоль строк вашего комментария, используя . Заметьте, однако, что cdata-section-elements
работает только на выходе, указывая, что выход XML-элементы, которые вы хотите напечатать, как разделы CDATA вместо обычного старого персонажа данные. Это не имеет никакого отношения к fetching данные.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output cdata-section-elements="foo"/>
<xsl:template match="/">
<foo>
<xsl:value-of select="node"/>
</foo>
</xsl:template>
</xsl:stylesheet>
выводит
<?xml version="1.0"?>
<foo><![CDATA[This is sample text]]></foo>
некоторые другие простые шаги для достижения этого;
использовать W3cschools редактор, чтобы попробовать.
пример XML-файла :
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<catalog>
<cd>
<disk id="title"><![CDATA[Sample xml]]></disk >
<disk id="artist"><![CDATA[Vijay]]></disk >
</cd>
</catalog>
Пример файла XSL:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="/catalog/cd/disk[@id='title']"/></td>
<td><xsl:value-of select="/catalog/cd/disk[@id='artist']"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Окончательный результат;
для выходных разделов CDATA:
вы должны использовать xsl:output/@cdata-section-elements
. От http://www.w3.org/TR/xslt#output
атрибут cdata-section-elements содержит список, разделенный пробелами имен qname. Каждый QName расширяется в расширенное имя с использованием пространства имен заявления, касающиеся xsl: выходной элемент, в котором QName происходит; если есть значение по умолчанию пространство имен, оно используется для Имен QNames, которые не имеют приставки. Этот расширение выполняется до слияния несколько xsl: выходные элементы в a одиночный эффективный xsl: элемент выхода. Если развернуто-имя родителя текстовый узел является членом списка, затем текстовый узел должен выводиться как раздел CDATA.
кроме того Пупкин, конечно.
вы не можете выбрать разделы CDATA с XPath. Согласно http://www.w3.org/TR/xpath/#data-model
там семь типов узлов:
корневого узла
узлы элемента
текстовые узлы
узлы атрибута
пространства имен узлов
обработка узлов инструкция
комментарий узлов
и от http://www.w3.org/TR/xpath/#section-Text-Nodes
каждый символ в разделе CDATA рассматриваются как символьные данные. Таким образом,
<![CDATA[<]]>
в исходном документе будет рассматриваться так же, как <.><![CDATA[ и и все появление<
и&
были заменены<
и&
соответственно.
единственное решение, которое я нашел в интернете, что работает это -
{XSLT}
<title>
<xsl:text disable-output-escaping="yes"><![CDATA[ <![CDATA[ ]]></xsl:text>
<xsl:value-of select="label" disable-output-escaping="yes"/>
<xsl:text disable-output-escaping="yes"><![CDATA[]]]]><![CDATA[>]]></xsl:text>
</title>
однако это не самое чистое решение, особенно если вам нужно реализовать это в различных частях вашего XSLT. Кроме того, если ваш входной XML уже имеет CDATA (т. е. вы пытаетесь сохранить CDATA), используя disable-output-escaping, не будет работать, так как к тому времени CDATA уже был проанализирован движком XSLT, и все, что останется, это содержимое, которое может в конечном итоге нарушить XML.
вот мой решение -
в зависимости от того, как вы используете XSLT, можно использовать внешние/вводимые функции. Делая это, вы можете легко минимизировать количество кода, который вы пишете, и в конечном итоге с гораздо более чистым шаблоном:
{C#}
public string CDATAWrap(string data)
{
return "<![CDATA[" + data + "]]>";
}
{XSLT}
<title>
<xsl:value-of select="CDataType:CDATAWrap(label)" disable-output-escaping="yes" />
</title>