Этого можно добиться с помощью атрибута cdata-section-elements
элемента xsl:output
, который указывает все элементы, которые должны выводиться в секциях CDATA
.
Поэтому используйте следующий XSLT-1.0:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" cdata-section-elements="to from heading body" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />
<!-- Identity template -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Обратите внимание, что cdata-section-elements
обозначает элементы to from heading body
для включения их содержимого в раздел CDATA
. шаблон идентификации просто копирует весь файл, относящийся к этому.
Если ваши элементы находятся в пространстве имен, вы должны поставить префикс имен элементов в cdata-section-elements
с помощьюсоответствующий префикс пространства имен.
Например, если у вас есть следующий XML с пространством имен в корневом элементе, все дочерние узлы также находятся в этом пространстве имен.
<?xml version="1.0" encoding="utf-8"?>
<Bank xmlns="http://xxyy.x.com" Operation="Create">
<Customer type="random">
<CustomerId>Id10</CustomerId>
<CountryCode>CountryCode19</CountryCode>
<LanguageCode>LanguageCode20</LanguageCode>
<AddressArray>
<Address type="primary">
<StreetAddress>179 Alfred St</StreetAddress>
<City>Fortitude Valley</City>
<County>GR</County>
<Country>India</Country>
</Address>
</AddressArray>
</Customer>
</Bank>
Используйте этоXSLT (обратите внимание на объявление пространства имен в элементе xsl:stylesheet
):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:ns0="http://xxyy.x.com">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" cdata-section-elements="ns0:CustomerId ns0:CountryCode ns0:LanguageCode ns0:StreetAddress ns0:City ns0:County ns0:Country" omit-xml-declaration="yes" />
<!-- Identity template -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Убедитесь, что пространство имен XSLT соответствует пространству имен XML, здесь оба значения http://xxyy.x.com
, но в вашемДля примера XML это xxyy.x.com
.
РЕДАКТИРОВАТЬ 2:
Если у вас есть большое количество элементов, вы можете добавить их все в cdata-section-elements
(возможно, создавая его по другой таблице стилей) или используйте решение, которое я нашел здесь: Обтекание всех элементов в CDATA .Это своего рода хак.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />
<xsl:variable name="CDATABegin" select="'<![CDATA['" />
<xsl:variable name="CDATAEnd" select="']]>'" />
<!-- Identity template -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="text()[normalize-space()]">
<xsl:value-of select="$CDATABegin" disable-output-escaping="yes"/>
<xsl:value-of select="." disable-output-escaping="yes"/>
<xsl:value-of select="$CDATAEnd" disable-output-escaping="yes"/>
</xsl:template>
</xsl:stylesheet>
Оборачивает все непустые узлы text()
в разделах CDATA.Но и здесь вы должны упомянуть все элементы в правилах сопоставления шаблонов, содержащих код переноса CDATA.
Какой вариант будет проще применить, зависит от большего сценария.