Как мне сериализовать вывод из набора узлов в xslt 1.0? - PullRequest
0 голосов
/ 22 марта 2019

Я работаю с некоторыми XML внутри XSLT.Я хочу сохранить его раздел в узле контента.Я оставил узел CDATA из этого примера.

Когда я беру xml как этот, он сбежал, т.е.&lt; = <</p>

<content name="test”>
      <xsl:copy-of select="//content[@name='something']/node()" />
</content>

Но мне нужно выполнить некоторую обработку данных, прежде чем я сохраню их в узле контента.У меня есть вызов xsl: for-each, и он зацикливает сохранение разделов.Однако, когда я вызываю подобную команду, я не могу получить XML для выхода.

<xsl:for-each select="exsl:node-set($xml)//data">
    <content name="test">
              <xsl:copy-of select="./node()" />
    </content>

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

Я действительно хочу что-то вроде:

<content name="test">
          &lt;data&gt;Some data&lt;\data&gt;
        </content>

Ввод будет выглядеть примерно так:

<root>
<data>Some data</data>
<data>more data</data>
</root>

Это упрощение данных.В узле данных будут дополнительные узлы xml.

1 Ответ

2 голосов
/ 22 марта 2019

Эван Ленц имеет основанную на XSLT 1 реализацию сериализации XML на http://lenzconsulting.com/xml-to-string/:, если вы используете ее, например,

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:import href="http://lenzconsulting.com/xml-to-string/xml-to-string.xsl"/>

  <xsl:output indent="yes" cdata-section-elements="content"/>

  <xsl:template match="/">
      <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="@* | node()">
      <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
  </xsl:template>

  <xsl:template match="data">
      <content>
          <xsl:apply-templates select="." mode="xml-to-string"/>
      </content>      
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / pPzifpn /4

Если процессором является libxslt, то это может позволить вам реализовать функцию расширения, например, PHP позволяет вызывать функции PHP, а DOMDocument в PHP имеет функцию saveXML для сериализации.так что вы можете позвонить из XSLT:

<?php

function serializeNode($node) {
  return $node[0]->ownerDocument->saveXML($node[0]);
}

$xml = <<<EOT
<root>
<data>Some data</data>
<data>more data</data>
</root>
EOT;

$xsl = <<<EOT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:php="http://php.net/xsl"
    exclude-result-prefixes="php"
    version="1.0">

  <xsl:output indent="yes" cdata-section-elements="content"/>

  <xsl:template match="/">
      <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="@* | node()">
      <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
  </xsl:template>

  <xsl:template match="data">
      <content>
          <xsl:value-of select="php:function('serializeNode', .)"/>
      </content>      
  </xsl:template>

</xsl:stylesheet>
EOT;

$doc = new DOMDocument();
$doc->loadXML($xml);

$proc = new XSLTProcessor();
$proc->registerPHPFunctions('serializeNode');

$sheet = new DOMDocument();
$sheet->loadXML($xsl);

$proc->importStylesheet($sheet);

echo $proc->transformToXml($doc);

?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...