XSLT - Как управлять CDATA как общим контентом? - PullRequest
0 голосов
/ 22 февраля 2019


Я пытаюсь использовать xslt для рендеринга xml-файла, сгенерированного программным обеспечением, используемым на моей работе.В xml есть контент CDATA.Когда я преобразую его, содержимое CDATA отображается в виде текста, но мне бы хотелось, чтобы оно не отображалось.Я нашел способ сделать его пустым, чтобы ничего не появлялось, пока мне не нужно его использовать, но я должен управлять всеми делами.

Мой вопрос: как я могу управлять всем контентом CDATA как стандартным текстом(доступно со значением of), чтобы он не появлялся, пока я не выбрал его для рендеринга?

XML-файл выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<Domain>
  <Properties>
    <Property id="DOM00000" key="mykey1" value="value1"/>
    <Property id="DOM00001" key="mykey2" value="value2"/>
  </Properties>
  <Tokens>
    <Token name="token1" comment=""><![CDATA[mydata1---blah-blah-blah]]></Token>
    <Token name="token2" comment=""><![CDATA[mydata2---blah-blah-blah]]></Token>
  </Tokens>
  <Resources>
    <Resource name="res1" type="W" current="0">
      <Value><![CDATA[10]]></Value>
    </Resource>
    <Resource name="res2" type="W" current="0">
      <Value><![CDATA[10]]></Value>
    </Resource>
  </Resources>
</Domain>

XSL-файл, которым я являюсьиспользуется вот это:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Domain/Properties">
  <table border="1">
    <tr bgcolor="#9acd32">
      <th style="text-align:left">id</th>
      <th style="text-align:left">key</th>
      <th style="text-align:left">value</th>
    </tr>
    <xsl:for-each select="/Domain/Properties/Property">
    <tr>
      <td><xsl:value-of select="@id" /></td>
      <td><xsl:value-of select="@key" /></td>
      <td><xsl:value-of select="@value" /></td>
    </tr>
    </xsl:for-each>
  </table>
  </xsl:template>
  <xsl:template match="/Domain/Tokens/Token">
  </xsl:template>
</xsl:stylesheet> 

Редактировать Вот что я использую:

<form method="POST">
    <label for="xmlfileinput">Fichier XML</label><input type="file" name="myxmlfile" id="xmlfileinput" accept=".xml"><br>
    <label for="xslfileinput">Fichier XSL</label><input type="file" name="myxslfile" id="xslfileinput" accept=".xsl"><br>       
    <input type="button" onclick="handleFiles()">
</form>

function handleFiles(e) {
    var myxmlfile = document.getElementById("xmlfileinput").files;
    var myxslfile = document.getElementById("xslfileinput").files;
    var xmlreader = new FileReader();
    var xslreader = new FileReader();
    xmlreader.onload = function() {
        var xml = new DOMParser().parseFromString(xmlreader.result, "text/xml");
        xslreader.onload = function() {
            var xsl = new DOMParser().parseFromString(xslreader.result, "text/xml");
            if (window.ActiveXObject /*|| xhttp.responseType == "msxml-document"*/)
              {
              ex = xml.transformNode(xsl);
              document.getElementById("example").innerHTML = ex;
              }
            // code for Chrome, Firefox, Opera, etc.
            else if (document.implementation && document.implementation.createDocument)
              {
              xsltProcessor = new XSLTProcessor();
              xsltProcessor.importStylesheet(xsl);
              resultDocument = xsltProcessor.transformToFragment(xml, document);
              while (document.getElementById("example").firstChild) {
document.getElementById("example").removeChild(document.getElementById("example").firstChild);
                }
             document.getElementById("example").appendChild(resultDocument);
              }
        };
        xslreader.readAsText(myxslfile[0]); 
    };
    xmlreader.readAsText(myxmlfile[0]);   
}

В результате с этими файлами "mydata ..." изжетоны не показаны, но "10" из Ресурсов здесь.

Спасибо

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Я думаю, что проблема здесь не в элементах, содержащих разделы CDATA, а в шаблоне соответствия вашего шаблона.

Вы начинаете с:

<xsl:template match="/Domain/Properties">

, что оставляет других потомков корняэлемент Domain, а именно Tokens и Resources, для обработки другими шаблонами.

У вас есть шаблон, соответствующий Token, но нет шаблона, соответствующего Resource.Таким образом, Resources (как и любые другие ветви, которые может иметь ваш XML) обрабатывается правилами встроенного шаблона .Это приводит к тому, что all их текст (не только текст в разделах CDATA) копируется в вывод.

Это уже упоминалось в предыдущем ответе.Однако решение состоит не в том, чтобы преследовать отдельных лошадей, а в том, чтобы закрыть дверь сарая:

XSLT 1.0

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

<xsl:template match="/Domain">
  <table border="1">
    <tr bgcolor="#9acd32">
      <th style="text-align:left">id</th>
      <th style="text-align:left">key</th>
      <th style="text-align:left">value</th>
    </tr>
    <xsl:for-each select="Properties/Property">
    <tr>
      <td><xsl:value-of select="@id" /></td>
      <td><xsl:value-of select="@key" /></td>
      <td><xsl:value-of select="@value" /></td>
    </tr>
    </xsl:for-each>
  </table>
</xsl:template>

</xsl:stylesheet> 
0 голосов
/ 23 февраля 2019

У вас проблема со встроенными шаблонными правилами , особенно

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

Это означает, что весь документ пройден, достигнув Value элементов.

Решение: добавьте еще один пустой шаблон, такой как у вас уже есть.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Domain/Properties">
  <table border="1">
    <tr bgcolor="#9acd32">
      <th style="text-align:left">id</th>
      <th style="text-align:left">key</th>
      <th style="text-align:left">value</th>
    </tr>
    <xsl:for-each select="/Domain/Properties/Property">
    <tr>
      <td><xsl:value-of select="@id" /></td>
      <td><xsl:value-of select="@key" /></td>
      <td><xsl:value-of select="@value" /></td>
    </tr>
    </xsl:for-each>
  </table>
  </xsl:template>
  <xsl:template match="/Domain/Tokens/Token|/Domain/Resources"/>
</xsl:stylesheet>
...