0
votes

I would like to create xml like this:

<rns:RootElement xmlns:rns="urn:root-element" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:root-element root-element.xsd">
    <rns:DocumentWrapper>
        <ins:InnerDoc xmlns:ins="urn:inner-doc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:inner-doc inner-doc.xsd">
            <ins:Value>Some text</ins:Value>
        </ins:InnerDoc>
    </rns:DocumentWrapper>
</rns:RootElement>

With this template:

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">

    <rns:RootElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xmlns:rns="urn:root-element"
                     xsi:schemaLocation="urn:root-element root-element.xsd">
        <rns:DocumentWrapper>
            <ins:InnerDoc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                          xmlns:ins="urn:inner-doc"
                          xsi:schemaLocation="urn:inner-doc inner-doc.xsd">
                <ins:Value><xsl:value-of select="//*[local-name()='SomeNode']"/></ins:Value>
            </ins:InnerDoc>
        </rns:DocumentWrapper>
    </rns:RootElement>

</xsl:template>

But instead of result that i wanted this template gave me a little bit different result:

<rns:RootElement xmlns:rns="urn:root-element" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:root-element root-element.xsd">
    <rns:DocumentWrapper>
        <ins:InnerDoc xmlns:ins="urn:inner-doc" xsi:schemaLocation="urn:inner-doc inner-doc.xsd">
            <ins:Value>Some text</ins:Value>
        </ins:InnerDoc>
    </rns:DocumentWrapper>
</rns:RootElement>

As you can see, in transformation result, InnerDoc element lacks definition of xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" namespace, is there any way to prevent missing of this namespace?

1
To expand slightly on Martin Honnen's answer, I'd like to point out that the lack of the duplicated ins namespace declaration doesn't do anything. Any conformant XML processor will recognize that the ins namespace declaration on the root element also applies to this ins:InnerDoc element. Any conformant XSL processor that moves the location of this ins:InnerDoc element to some other location, where the declaration on the root element doesn't apply, will also add in the namespace declaration as needed.Eiríkr Útlendi
I know that, but this requirement goes from other system, and i don't really know would they receive my message properly without this namespace. Anyway, thank you for this comment!Владислав Синявин

1 Answers

1
votes

As the namespace declaration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" is present on the root element it is in scope for the child and descendant elements and does not need to be repeated for the ins:InnerDoc element. I don't know of any way to enforce the output of duplicated namespace declarations with XSLT.

Some other APIs have a way to suppress them, like LINQ to XML with the OmitDuplicateNamespaces on the SaveOptions https://msdn.microsoft.com/en-us/library/system.xml.linq.saveoptions(v=vs.110).aspx, but that option was added rather to suppress duplicate namespace declarations when serializing LINQ to XML trees, not to enforce them.