对于混合命名空间 XML 内容,如何防止在新创建的元素上出现冗余 xmlns: 定义?

For mixed-namespace XML content, how do I prevent redundant xmlns: definitions on newly created elements?

我有以下 HTML 文档,其中包含 MathML 命名空间元素:

<html>
  <head>
    <title>Equations</title>
  </head>
  <body>
    <p>

      <!-- MathML element -->
      <math xmlns="http://www.w3.org/1998/Math/MathML">
        <mrow>
          <mi>m</mi>
        </mrow>
      </math>

    </p>
  </body>
</html>

我在顶级(默认)和 MathML 命名空间中有以下 matches/modifies/creates 内容的 XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:m="http://www.w3.org/1998/Math/MathML"
  exclude-result-prefixes="xs m">

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

  <!-- match and create elements in top-level (default) namespace -->
  <xsl:template match="body">
    <xsl:copy>
      <xsl:attribute name="MATCHED" select="1"/>
      <div CREATED="1">
        <xsl:apply-templates select="p"/>
      </div>
    </xsl:copy>
  </xsl:template>

  <!-- match and create elements in nested namespace -->
  <xsl:template match="m:mrow">
    <xsl:copy>
      <xsl:attribute name="MATCHED" select="1"/>
      <m:mfenced CREATED="1">
        <xsl:apply-templates select="m:mi"/>
      </m:mfenced>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

我指定 m: 命名空间前缀应该通过 exclude-result-prefixes 抑制,但它们仍然出现在输出中新创建的 MathML 元素上(注意模板创建的命名空间 mfenced元素):

<html>
   <head>
      <title>Equations</title>
   </head>
   <body MATCHED="1">
      <div CREATED="1">
         <p>

            <!-- MathML element -->
            <math xmlns="http://www.w3.org/1998/Math/MathML">
               <mrow MATCHED="1">
                  <m:mfenced xmlns:m="http://www.w3.org/1998/Math/MathML" CREATED="1">
                     <mi>m</mi>
                  </m:mfenced>
               </mrow>
            </math>

         </p>
      </div>
   </body>
</html>

如何抑制这些?

我使用的解决方案是在每个处理 nested-namespace 内容的 <xsl:template> 元素上定义一个本地命名空间。模板中的所有 match/test 表达式仍然需要显式命名空间引用。

在上面的样式表中,两个变化是

  <xsl:template match="m:mrow" xmlns="http://www.w3.org/1998/Math/MathML">
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ added

  <mfenced CREATED="1">
   ^--- explicit namespace removed
    ...
  </mfenced>
   ^--- explicit namespace removed

通过这些更改,我们得到的输出与输入一样干净:

<html>
   <head>
      <title>Equations</title>
   </head>
   <body MATCHED="1">
      <div CREATED="1">
         <p>

            <!-- MathML element -->
            <math xmlns="http://www.w3.org/1998/Math/MathML">
               <mrow MATCHED="1">
                  <mfenced CREATED="1">
                     <mi>m</mi>
                  </mfenced>
               </mrow>
            </math>

         </p>
      </div>
   </body>
</html>

感谢 Martin、Wendell、Liam 和 David(在 Mulberry XSLT 邮件列表中)和 Radu(在 Syncro Soft)帮助我理解名称空间!