XSLT (1.0) Как сохранить HTML-теги при переносе значения элемента в тег CDATA - PullRequest
1 голос
/ 22 марта 2019

У меня есть XML с текстовыми элементами, которые могут включать теговый текст и, в зависимости от значения атрибута элементов, я знаю, является ли содержимое инкапсулированным CDATA или XHTML.

Поскольку я не могу иметь / создавать дочерние элементы вТекстовый элемент, который мне нужно будет инкапсулировать, если я получу XHTML.

Это всего лишь один из многих элементов, которые мне нужно преобразовать в моем XSLT

Короткий образец XML

  <ONIXMessage release="3.0" xmlns="http://ns.editeur.org/onix/3.0/reference">
  <Product>
    <CollateralDetail>
      <TextContent>
        <Text textformat="05">
          <p>Requires internet connection for purchase, plus iPod or other Audible-compatible player or iTunes software on Mac OS X or Windows</p>
        </Text>
      </TextContent>
    </CollateralDetail>
  </Product>
  <Product>
    <CollateralDetail>
      <TextContent>
        <Text textformat="02"><![CDATA["Nogle dyr er farlige. Nogle dyr kan slå dig ihjel!"
Hvis det stod til Claras mor, var Clara aldrig blevet vildheks. Hun er bange for at Clara skal komme noget til, og det viser sig at der er en god grund. Den vilde verden ER et farligt sted – ikke mindst nu hvor Bravita Blodsunge er ved at bryde fri af det fængsel der har holdt hende fanget i 400 år ...

"Blodsungen" er fjerde bog i serien om Clara, hendes kærlighed til dyr og hendes kamp for at overleve som vildheks i en verden hvor magi ikke ligefrem er barnemad.]]></Text>
      </TextContent>
    </CollateralDetail>
  </Product>
</ONIXMessage>

Я наконец попробовал это, и это каким-то образом достигло цели.Просто HTML-теги не сохраняются.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
 xmlns:onix="http://ns.editeur.org/onix/3.0/reference"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xsl onix xsi">

    <xsl:output method="xml" indent="no" omit-xml-declaration="yes" />
<!--  cdata-section-elements="onix:BiographicalNote onix:Text" -->
    <xsl:template match="@* | node() ">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="//onix:TextContent/onix:Text ">
        <xsl:choose>
            <xsl:when test="//onix:TextContent/onix:Text/@textformat='05'">
                <xsl:element name="Text" xmlns="http://ns.editeur.org/onix/3.0/reference" >
                <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
                    <xsl:value-of select="current()"/>
                <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
                </xsl:element>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy-of select="current()"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

Это приведет к следующему (обратите внимание, тег

пропал в первом тексте)

<ONIXMessage release="3.0" xmlns="http://ns.editeur.org/onix/3.0/reference">
  <Product>
    <CollateralDetail>
      <TextContent>
        <TextType>11</TextType>
        <ContentAudience>02</ContentAudience>
        <Text><![CDATA[
          Requires internet connection for purchase, plus iPod or other Audible-compatible player or iTunes software on Mac OS X or Windows
        ]]></Text>
      </TextContent>
    </CollateralDetail>
  </Product>
  <Product>
    <CollateralDetail>
      <TextContent>
        <TextType>03</TextType>
        <ContentAudience>00</ContentAudience>
        <Text><![CDATA["Nogle dyr er farlige. Nogle dyr kan slå dig ihjel!"
Hvis det stod til Claras mor, var Clara aldrig blevet vildheks. Hun er bange for at Clara skal komme noget til, og det viser sig at der er en god grund. Den vilde verden ER et farligt sted – ikke mindst nu hvor Bravita Blodsunge er ved at bryde fri af det fængsel der har holdt hende fanget i 400 år ...

"Blodsungen" er fjerde bog i serien om Clara, hendes kærlighed til dyr og hendes kamp for at overleve som vildheks i en verden hvor magi ikke ligefrem er barnemad.]]></Text>
      </TextContent>
    </CollateralDetail>
  </Product>
</ONIXMessage>

У меня также естьпопытался использовать cdata-section-elements = "onix: Text"

Но вывод становится действительно странным с несколькими тегами cdata в выводе для 1 элемента, и единственное, что он не инкапсулирует, это фактически текст iхочу инкапсулировать

<BiographicalNote textformat="05"><![CDATA[
  ]]><p>A crime writer for over thirty years, Ruth Rendell has won one Crime Writers’ Association Silver Dagger Award, two Gold Daggers and, the supreme accolade, the Crime Writers’ Diamond Award for her outstanding contribution to the genre.</p><![CDATA[
]]></BiographicalNote>

Как мне решить, что мне нужно достичь?Почему html-теги удаляются из значения элемента, когда я пытаюсь инкапсулировать текст в код, который я сделал (... и это даже правильный подход?!)

1 Ответ

1 голос
/ 22 марта 2019

Спасибо, Тим C https://stackoverflow.com/users/7585/tim-c

Казалось, я не до конца понял природу value-of Решение было довольно близко.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
 xmlns:onix="http://ns.editeur.org/onix/3.0/reference"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xsl onix xsi">

    <xsl:output method="xml" indent="no" omit-xml-declaration="yes" />
<!--  cdata-section-elements="onix:BiographicalNote onix:Text" -->
    <xsl:template match="@* | node() ">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="//onix:TextContent/onix:Text ">
        <xsl:choose>
            <xsl:when test="//onix:TextContent/onix:Text/@textformat='05'">
                <xsl:element name="Text" xmlns="http://ns.editeur.org/onix/3.0/reference" >
                <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
                    <xsl:copy-of select="node()"/>
                <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
                </xsl:element>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy-of select="current()"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>
...