开发者

xsl namespace attribue add empty namespace in child element

I was adding a namespace in an element using xsl element namespace attribute. That adds empty namespace in child element in result.

Here is the XSL that adds namespace into element "Auto"

EDIT - short version of my xsl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="no"/>
<xsl:template match="/">
    <xsl:element name="Root">
        <xsl:element name="Auto" namespace="http://www.Root.com/XMLSchema/Auto">
            <xsl:element name="Applicant">
                <xsl:element name="ApplicantType">
                    <xsl:text>Applicant</xsl:text>
                </xsl:element>
            </xsl:element>
        </xsl:element>
        <xsl:element name="Life" namespace="http://www.Root.com/XMLSchema/Auto">
            <xsl:element name="Applicant">
                <xsl:element name="ApplicantType">
                    <xsl:text>Applicant</xsl:text>
                </xsl:element>
            </xsl:element>
        </xsl:element>
    </xsl:element>
</xsl:template>

Here is the xml that transformed by XSL

<Root>
<Auto xmlns="http://www.Root.com/XMLSchema/Auto"&g开发者_StackOverflowt;
    <Applicant xmlns="">
        <ApplicantType>Applicant</ApplicantType>
    </Applicant>
</Auto>
</Root>

If you see the Applicant element, transformation added xmlns="". How to remove this empty namespace?


We can help you better if you show the XSL that's producing the Applicant and ApplicantType elements. Also, you're confusing "namespace" and "namespace declaration" in your description of the problem... separating these two might help you grasp the solution

Your XSL code is apparently telling the processor to output the Applicant element in no namespace. (And therefore your code is probably wrong... you want Applicant to be in the same Auto namespace as its parent.) Since Applicant with no prefix would inherit the default namespace declaration from its parent, the output XML must "undeclare" the default namespace declaration, in order to put Applicant in no namespace as you requested.

For example, if your XSL code says:

<xsl:element name="Auto" namespace="http://www.Root.com/XMLSchema/Auto">
   <xsl:element name="Applicant">

then you are telling XSL to output the Applicant element in no namespace, as described above. To fix this, you can repeat the namespace:

<xsl:element name="Auto" namespace="http://www.Root.com/XMLSchema/Auto">
   <xsl:element name="Applicant" namespace="http://www.Root.com/XMLSchema/Auto">

or as @empo said, you can declare a namespace prefix and use it:

<xsl:stylesheet ... xmlns:auto="http://www.Root.com/XMLSchema/Auto">
   ...
      <auto:Auto>
         <auto:Applicant>
            <auto:ApplicantType>
   ...

or use a default namespace declaration in the stylesheet (or template):

<xsl:stylesheet ... xmlns="http://www.Root.com/XMLSchema/Auto">
   ...
      <xsl:element name="Auto">
         <xsl:element name="Applicant">
   ...


Don't think in terms of namespace declarations in the surface syntax of the XML, think about element names as (uri, localname) pairs. If you create an Applicant element that's not in any namespace, but it's parent is in a namespace, then the serializer is going to add xmlns="" to ensure that your wishes are respected (i.e. having Applicant in a different namespace from its parent element). On the other hand, if you want Applicant to be in the namespace "http://www.Root.com/XMLSchema/Auto", then you need to ensure that it is created in this namespace. You haven't shown the code that created it, so we can't tell exactly what you did wrong.


Either the Applicant and ApplicantType elements have no namespace, in which case the empty namespace declaration is correct, or, they should be in the same namespace as the Auto element (or, for completeness, in yet another namespace). In the latter cases you must fix your XSL transformation.


Your output document is:

<Root>
<Auto xmlns="http://www.Root.com/XMLSchema/Auto">
    <Applicant xmlns="">
        <ApplicantType>Applicant</ApplicantType>
    </Applicant>
</Auto>
</Root>

And this is correct if you look at the way you have specified the literal namespace URI in the transform. In fact you have qualified the elements as follows:

{}Root
 -{http://www.Root.com/XMLSchema/Auto}Auto
  -{}Applicant
   -{}ApplicantType

You have not qualified Root, as well as Applicant and ApplicantType. Because unqualified names are treated by default as elements belonging to null namespace (xmlns=""), your output document must specify this at least in those nodes which may cause ambiguity or wrong interpretation of the document.

What you probably have missed is that in XSLT when in a transform you indicate a literal namespace URI for a specific element you are qualifying that element only (nor its children nor any other descendant). So in XSLT, if you want to save you from having to define a namespace for each element being declared you have to go with a global default namespace. This will correctly qualify every element inside the namespace and also omit most of the namespace declarations in your output. You might also want to use:

exclude-result-prefixes="#default"

to remove superfluous namespace declarations.

Think then of adding a global namespace with prefix only if you really need it (e.g. you know you will have naming conflicts in your output document).

Your question:

How to remove this empty namespace?

You should ask yourself now: where to qualify my elements (and its descendants) (once and for all)?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜