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

Deadly 提交于 2021-02-11 14:17:38

问题


I have the following HTML document that contains a MathML-namespaced element:

<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>

I have the following XSLT that matches/modifies/creates content in both the top-level (default) and MathML namespaces:

<?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>

I specify that the m: namespace prefix should be suppressed via exclude-result-prefixes, but they still appear on newly-created MathML elements in the output (note the namespace on the template-created mfenced element):

<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>

How do I suppress these?


回答1:


The solution I used was to define a local namespace on each <xsl:template> element that processes the nested-namespace content. Explicit namespace references are still needed for all match/test expressions within the template.

In the stylesheet above, the two changes are

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

and

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

With these changes, we get output as clean as the input:

<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>

Thanks to Martin, Wendell, Liam, and David (on the Mulberry XSLT mailing list) and to Radu (at Syncro Soft) for helping me understand namespaces!



来源:https://stackoverflow.com/questions/64716407/for-mixed-namespace-xml-content-how-do-i-prevent-redundant-xmlns-definitions-o

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!