html - 将节点的内容克隆到不同的命名空间

标签 html xslt namespaces

在对实际情况有了更多了解后,我更新了原始问题的标题和文本。我将这种症状误解为没有保留空白,而真正发生的事情是 HTML 元素没有被解释为 HTML。

我正在编写从 WADL 文档到 HTML 的转换。我需要克隆 WADL 的内容 <doc>元素同时保留空格,因为 <doc>元素可能包含 HTML 元素,如 <pre>在将命名空间更改为 HTML 时关心空格。

WADL 样本 <doc>元素:

<doc xml:lang="en" title="Some Representation">
    Sample representation:
    <pre><![CDATA[
        <MyRoot>
            <MyChild awesome="yes"/>
        </MyRoot>
    ]]></pre>
</doc>

这是我目前正在改变的方式:
<xsl:apply-templates select="wadl:doc"/>

...

<xsl:template match="wadl:doc">
    <xsl:if test="@title">
        <p><strong><xsl:value-of select="@title"/></strong></p>
    </xsl:if>
    <p><xsl:copy-of select="*|node()"/></p>
</xsl:template>

我看到的是复制的内容<pre>元素具有折叠的空白不被解释为 <pre>元素,因此表示样本看起来不正常。我如何指示 XSL 输出在复制 <doc> 的内容时保留空白覆盖命名空间元素?或者这仅仅是我选择 <doc> 内容的方式的问题吗?元素?

更新

在确认这可能是输出命名空间问题后,我创建了以下最小设置来进行实验:

XML:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="doc_test.xsl"?>
<application xmlns="http://wadl.dev.java.net/2009/02">
    <doc>
        <p>This is an HTML paragraph</p>
        <pre>
And this
is a
preformatted
block of
text.
        </pre>
    </doc>
</application>

XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:wadl="http://wadl.dev.java.net/2009/02">
<xsl:output
    doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>
<xsl:template match="wadl:application">
<html>
<head>
    <title>Doc Test</title>
</head>
<body>
<xsl:apply-templates select="wadl:doc"/>
</body>
</html>
</xsl:template>

<xsl:template match="wadl:doc">
    <xsl:copy-of select="node()"/>
</xsl:template>

</xsl:stylesheet>

当我检查 <p> 的 DOM 节点时或 <pre> Firefox 上的元素,元素的命名空间指向 WADL 命名空间,并且它们不能正确呈现为 HTML(它们看起来像纯文本)。当我在 Chrome 上做同样的事情时,命名空间是 XHTML,元素呈现为正确的 XHTML 元素。

所以,我猜,因为在 <doc>我的原始 WADL 文档的元素我没有明确使用命名空间前缀,我需要找到一种很好的方法来强制 <doc> 的内容使用 XHTML 命名空间,或者简单地向 <doc> 的内容添加一个 XHTML 命名空间前缀(更多的工作,但似乎是正确的方法)。

最佳答案

我无法使用提供的 XSLT 代码重现该问题 .

我稍微修改了一下,添加了 wadl:命名空间:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:wadl="some:wadl-namespace"
  exclude-result-prefixes="wadl"
 >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="wadl:doc">
    <xsl:if test="@title">
        <p><strong><xsl:value-of select="@title"/></strong></p>
    </xsl:if>
    <p><xsl:apply-templates select="node()"/></p>
 </xsl:template>

 <xsl:template match="wadl:pre">
   <pre>
     <xsl:apply-templates select="node()"/>
   </pre>
 </xsl:template>

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

当此转换应用于此 XML 文档时 :
<doc xml:lang="en" title="Some Representation"
  xmlns="some:wadl-namespace"
>
    Sample representation:
    <pre><![CDATA[
        <MyRoot>
            <MyChild awesome="yes"/>
        </MyRoot>
    ]]></pre>
</doc>

结果是用所需的空白 产生的:
<p><strong>Some Representation</strong></p>
<p>
    Sample representation:
    <pre>
        &lt;MyRoot&gt;
            &lt;MyChild awesome="yes"/&gt;
        &lt;/MyRoot&gt;
    </pre>
</p>

我怀疑您的浏览器可能无法正确解释 <pre>当它在自定义命名空间中时(IE 不介意)。

请注意我的转换中的命名空间剥离。 如果单独的命名空间剥离不能在您的浏览器中产生所需的结果,您需要创建 <pre> (以及从源 XML 文档复制的任何其他 html 标签)在 (X)Html 命名空间中,通过使用
<xsl:element name="{name()}" namespace="http://www.w3.org/1999/xhtml">
操作说明。

关于html - 将节点的内容克隆到不同的命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3143939/

相关文章:

xml - 用于清理数据的 XSLT

xslt - XSL 媒体 :content - Trimming strings in XSLT

python - 使用元素树和 Python 进行 XML 命名空间解析搜索

typescript :跨多个文件的同一命名空间内的可见性

sql-server - SQL Server - 查询缺少命名空间的 XML 列

javascript - 凭头衔给李上课?

javascript - 从 ES6 到 HTML 的多行模板字符串(不包括换行符)

html - 如何用颜色填充 unicode (star :\u2605) character only half way in css/html?

php - BeautifulSoup 和 php/html 文件

xml - 从 XSL 中的 CDATA 标记中呈现 HTML 标记