XSLT - 如何将 CDATA 作为通用内容进行管理?
XSLT - How to manage CDATA as common content?
我正在尝试使用 xslt 呈现由我工作中使用的软件生成的 xml 文件。
xml中有一些CDATA内容。当我转换它时,CDATA 的内容显示为文本,但我希望它只是不显示。
我找到了一种使它为空的方法,这样在我不需要利用它时什么也不会出现,但我必须处理所有情况。
我的问题是:
我如何将所有 CDATA 内容作为标准文本(可通过 value-of 访问)进行管理,以便在我不 select 渲染它时它不会出现?
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”在这里。
谢谢
您的 built-in template rules 有问题,尤其是
<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>
我认为这里的问题不在于包含 CDATA 部分的元素,而在于模板的匹配模式。
您开始于:
<xsl:template match="/Domain/Properties">
留下根元素 Domain
的其他子元素 - 即 Tokens
和 Resources
- 由其他模板处理。
您确实有一个匹配 Token
的模板,但没有匹配 Resource
的模板。因此 Resources
(以及您的 XML 可能拥有的任何其他分支)由 built-in template rules 处理。这导致 所有 它们的文本(不仅是 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>
我正在尝试使用 xslt 呈现由我工作中使用的软件生成的 xml 文件。
xml中有一些CDATA内容。当我转换它时,CDATA 的内容显示为文本,但我希望它只是不显示。
我找到了一种使它为空的方法,这样在我不需要利用它时什么也不会出现,但我必须处理所有情况。
我的问题是: 我如何将所有 CDATA 内容作为标准文本(可通过 value-of 访问)进行管理,以便在我不 select 渲染它时它不会出现?
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”在这里。
谢谢
您的 built-in template rules 有问题,尤其是
<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>
我认为这里的问题不在于包含 CDATA 部分的元素,而在于模板的匹配模式。
您开始于:
<xsl:template match="/Domain/Properties">
留下根元素 Domain
的其他子元素 - 即 Tokens
和 Resources
- 由其他模板处理。
您确实有一个匹配 Token
的模板,但没有匹配 Resource
的模板。因此 Resources
(以及您的 XML 可能拥有的任何其他分支)由 built-in template rules 处理。这导致 所有 它们的文本(不仅是 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>