How to avoid all namespace occurrence in output by writing a single statement in XSLT

前端 未结 4 1309
忘了有多久
忘了有多久 2021-02-20 04:09

I wrote \"exclude-result-prefixes\" and even then I see the name space occurrence appearance in output.



        
相关标签:
4条回答
  • 2021-02-20 04:21

    The exclude-result-prefixes attribute of xsl:stylesheet, when specified as "yes" mandates the removal of any namespace nodes of a litreral result element (only) that are inherited and don't define both the namespace-uri and prefix of the literal result element.

    The following statement in the answer by Markus Jarderot is wrong:

    "exclude-result-prefixes just removes the xmlns:foo="" attributes on the root tag of the result."

    Here is a counter-example:

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

    When this transformation is applied on any XML document (not used), the result is:

    <z:x xmlns:z="z:z">
       <z:y/>
    </z:x>
    

    We see that:

    1. The namespace node (and definition) for the namespace with value (namespace-uri) "z:z" is not removed from the top element (what Markus Jarderot calls "root tag").

    2. The namespace with prefix "z" isn't removed from any literal element at all.

    That shows the simple fact that specifying exclude-result-prefixes="yes" cannot remove a namespace if it isn't on an LRE (Literal Result Element) and even if a namespace node is on an LRE but is defining the namespace to which the element belongs.

    In order to remove an element from the namespace it belongs to, or remove namespaces from non-LRE elements, we need to specify some additional processing.

    One example is a replacement of the traditional identity rule with the following:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:template match="node()[not(self::*)]">
         <xsl:copy>
           <xsl:apply-templates/>
         </xsl:copy>
     </xsl:template>
    
     <xsl:template match="*">
      <xsl:element name="{local-name()}">
       <xsl:apply-templates select="node()|@*"/>
      </xsl:element>
     </xsl:template>
    
     <xsl:template match="@*">
      <xsl:attribute name="{local-name()}">
       <xsl:value-of select="."/>
      </xsl:attribute>
     </xsl:template>
    </xsl:stylesheet>
    

    The above transformation replaces any element or attribute with a corresponding element or attribute that belongs to "no namespace". One potential use for it is to convert a document with a default namespace to a document without such.

    For example, when applied on the following source XML document:

    <z:x xmlns:z="z:z">
        <z:y z:attr="someValue"/>
    </z:x>
    

    the result of the transformation is:

    <x>
       <y attr="someValue"/>
    </x>
    

    Finally a warning:

    This transformation may be harmful if applied on documents that contains two elements (or two attributes) that have the same local name but belong to two different namespaces -- the transformation replaces these with elements (or attributes) that both belong to the same namespace (no namespace).

    0 讨论(0)
  • 2021-02-20 04:29

    exclude-result-prefixes just removes the xmlns:foo="" attributes on the root tag of the result. The tags are still bound to the same namespace. Since the tags does not have any matching prefixes, the default namespace is used.

    If you wish to remove the namespaces completely, you could use the following stylesheet:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml" indent="no"/>
    
        <xsl:template match="/|comment()|processing-instruction()">
            <xsl:copy>
                <xsl:apply-templates/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="*">
            <xsl:element name="{local-name()}">
                <xsl:apply-templates select="@*|node()"/>
            </xsl:element>
        </xsl:template>
    
        <xsl:template match="@*">
            <xsl:attribute name="{local-name()}">
                <xsl:value-of select="."/>
            </xsl:attribute>
        </xsl:template>
    </xsl:stylesheet>
    

    (source: TEI wiki)

    0 讨论(0)
  • 2021-02-20 04:39

    Try to use this in your stylesheet:

    <stylesheet
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:xhtml="http://www.w3.org/1999/xhtml"   ...etc >
    

    I had this inside some tags: xmlns="http://www.w3.org/1999/xhtml, so I added those 2 lines and its ok now.

    This source helped me: http://xmlplease.com/xhtmlxhtml

    0 讨论(0)
  • 2021-02-20 04:41

    The exclude-result-prefixes attribute will (in some situations) remove unused namespace declarations from the output. It will never remove namespaces that are actually in use for element and attributes in the result: that is, it will never change the names of the elements and attributes to put them in a different namespace (or in no namespace). If you want elements not to be in a namespace, you must avoid putting them in a namespace when you generate them, whether by using literal result elements, xsl:element, or xsl:copy.

    0 讨论(0)
提交回复
热议问题