复制没有 'xmlns="" ' 的 XML 的整个节点

Copy entire node of an XML without 'xmlns="" '

我有以下 XML(文件:emcsh.xml):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="tohtml.xsl"?>
...
<root>
  <el>
    <d>Some text with <kbd>code</kbd> and <em>prose</em>.</d>
  </el>
</root>

进行以下转换(文件:tohtml.xsl):

<?xml version='1.0' encoding='utf-8'?>
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="http://www.w3.org/1999/xhtml">
...
<xsl:template match="d">
  <xsl:copy-of select="node() | @*"/>
</xsl:template>
...
<xsl:if test="d">
  <div class="tipper">
    <xsl:apply-templates select="d"/>
  </div>
</xsl:if>

使用以下管道处理文件后:

$ xsltproc tohtml.xsl emcsh.xml > emcsh.html && xmllint --format emcsh.html -o emcsh.html

结果字符串是:

...
<div class="tipper">
  Some text with <kbd xmlns="">code</kbd> and <em xmlns="">prose</em>.
</div>
...

几乎完美,但是如果没有空属性,我如何进行转换xmlns=""

谢谢。

发生这种情况是因为 XSLT 的默认名称空间是 http://www.w3.org/1999/xhtml,这意味着文字元素(如 <div> 那里)将在该名称空间中。

当它复制空命名空间中的 <kbd> 时,它会插入 xmlns="" 以指示命名空间的更改。

保留 http://www.w3.org/1999/xhtml 默认名称空间并且在输出中不包含 xmlns="" 的唯一方法是让 XSLT 将输入元素转换为 http://www.w3.org/1999/xhtml 名称空间。

您可以这样做:

<?xml version='1.0' encoding='utf-8'?>
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="http://www.w3.org/1999/xhtml">
...
<xsl:template match="d">
  <xsl:apply-templates select="node() | @*"/>
</xsl:template>

<xsl:template match="d//*">
  <xsl:element name="{local-name()}" namespace="http://www.w3.org/1999/xhtml">
    <xsl:apply-templates select="node() | @*" />
  </xsl:element>
</xsl:template>
...
<xsl:if test="d">
  <div class="tipper">
    <xsl:apply-templates select="d"/>
  </div>
</xsl:if>