1

I want to remove all namespaces from XML file and found my solution like this:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output indent="yes" method="xml" encoding="utf-8" omit-xml-declaration="yes"/>

   <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>

    <!-- template to copy attributes -->
    <xsl:template match="@*">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>

    <!-- template to copy the rest of the nodes -->
    <xsl:template match="comment() | text() | processing-instruction()">
        <xsl:copy/>
    </xsl:template>

</xsl:stylesheet>

How can I do other editing operations with this XML(creating new tags, search nodes) in this xslt just adding new xslt-code to previous example? I don't want to create two xslt files, delete namespaces with one and do my editing operations with another xslt-file.

Edit. For example, I have this xml source:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <soapenv:Body>
       <ns2:completeProductionPlan xmlns="http://ServiceManagement/OIS_Services_v01.00/common"
            xmlns:ns2="http://ServiceManagement/TechnicalOrderManagement/ProductionFulfillment_v01.00/types">
        <ns2:messageID>
            <value>9133235059913398501_9133235059913398860</value>
        </ns2:messageID>
    </ns2:completeProductionPlan>
    </soapenv:Body>
    </soapenv:Envelope>

and want to get this:

<?xml version="1.0" encoding="UTF-8"?>
<CompletePP >
<MessageId>9133235059913398501_9133235059913398860</MessageId>
</CompletePP> 

And all xslt operations I want to do in one xslt-file

2
  • You can do so simply by adding additional templates to this XSLT like you would to any other XSLT. You have to ask a more specific question if you want any information beyond that. Commented May 17, 2013 at 8:44
  • Just add more information to my question. Thanks Commented May 17, 2013 at 9:09

2 Answers 2

1

You can do any xslt operation you like to. Only think you have to attend to, are the name space uris in your original xml. You have to add name spaces prefixes for element names you like to access to your xslt. The name of the prefix can be different from xml, but it make reading easier if you use the same. Here a small example.
Input xml:

<?xml version="1.0"?>
<xml xmlns:ns0="uri:test">
<ns0:Testing>
    <ns0:Cedent>
        <ns0:Party>
            <ns0:Id Agency=""></ns0:Id>
            <ns0:Name>Canada</ns0:Name>
        </ns0:Party>
    </ns0:Cedent>
    <ns0:Broker>
        <ns0:Party>
            <ns0:Id Agency="Legacy">292320710</ns0:Id>
            <ns0:Name>Spain</ns0:Name>
        </ns0:Party>
    </ns0:Broker>
</ns0:Testing>
</xml>

With little changed to your style sheet to rename Party to test, and no name spaces in output. Try:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:t="uri:test" 
                exclude-result-prefixes="t" >

    <xsl:output indent="yes" method="xml" encoding="utf-8" omit-xml-declaration="yes"/>

    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>

    <!-- template to copy attributes -->
    <xsl:template match="@*">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>

    <!-- template to copy the rest of the nodes -->
    <xsl:template match="comment() | text() | processing-instruction()">
        <xsl:copy/>
    </xsl:template>
    <xsl:template match="t:Party">
        <test>
            <xsl:apply-templates select="@* | node()"/>
        </test>

    </xsl:template>

</xsl:stylesheet>

Which will generate following output:

<Testing>
    <Cedent>
        <test>
            <Id Agency=""/>
            <Name>Canada</Name>
        </test>
    </Cedent>
    <Broker>
        <test>
            <Id Agency="Legacy">292320710</Id>
            <Name>Spain</Name>
        </test>
    </Broker>
</Testing>
</xml>

Update because of update of question: For your example try this:

xmlns:common="http://ServiceManagement/OIS_Services_v01.00/common"
                exclude-result-prefixes="ns2 common" >

    <xsl:output indent="yes" method="xml" encoding="utf-8" omit-xml-declaration="yes"/>

    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>

    <!-- template to copy attributes -->
    <xsl:template match="@*">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>

    <!-- template to copy the rest of the nodes -->
    <xsl:template match="comment() | text() | processing-instruction()">
        <xsl:copy/>
    </xsl:template>
    <xsl:template match="/">
        <CompletePP>
            <MessageId>
                <xsl:apply-templates select="//ns2:messageID/common:value"/>
            </MessageId>

        </CompletePP>

    </xsl:template>

</xsl:stylesheet>

Which will generate the following output:

<CompletePP>
  <MessageId>
    <value>9133235059913398501_9133235059913398860</value>
  </MessageId>
</CompletePP>

Update because of comment: I couldn't access to the some elements(e.g. value) because that elements haven't any namespaces

Seems there is still a small misunderstanding. E.g the namespace of value is xmlns="http://ServiceManagement/OIS_Services_v01.00/common" because this is the default namespace for the context of value. This means value has a name space but not a namespace prefix. From xslt you need to use a namespace prefix for any element with namespace. Or you have to use local-name().

Sign up to request clarification or add additional context in comments.

4 Comments

Sorry. Don't understand your answer. I don't want add new namespaces. Just delete them all and work futher
To access element names which are belonging to an name space you have to add this name spaces to your xslt. The do not have to appear i output. Alternative you can access elements with *[local-name() = 'messageID'. Or you do it in tow passes. 1. Remove all name spaces. 2. Second xslt with any thing else.
Great thanks!) Now I understand your solution and will try to use it. I couldn't access to the some elements(e.g. value) because that elements haven't any namespaces. Now I see this solution!)
@ArthurPshenokov: Have a look to the update. Please also consider to mark the answer as valid.
0

In your example, you're not removing the namespaces at all. You're changing the XML completely. This would work in that case:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns2="http://ServiceManagement/TechnicalOrderManagement/ProductionFulfillment_v01.00/types"
    exclude-result-prefixes="ns2">
  <xsl:output method="xml" indent="yes" />
  <xsl:strip-space elements="*" />

  <xsl:template match="ns2:completeProductionPlan">
    <CompletePP>
      <xsl:apply-templates />
    </CompletePP>
  </xsl:template>

  <xsl:template match="ns2:messageID">
    <MessageId>
      <xsl:apply-templates />
    </MessageId>
  </xsl:template>
</xsl:stylesheet>

When run on your sample input, the result is:

<?xml version="1.0" encoding="utf-8"?>
<CompletePP>
  <MessageId>9133235059913398501_9133235059913398860</MessageId>
</CompletePP>

To handle the example you posted in the comments here, it would be:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns2="http://ServiceManagement/types"
    exclude-result-prefixes="ns2">
  <xsl:output method="xml" indent="yes" />
  <xsl:strip-space elements="*" />

  <xsl:template match="ns2:completeProductionPlan">
    <CompletePP>
      <xsl:apply-templates />
    </CompletePP>
  </xsl:template>

  <xsl:template match="ns2:messageID">
    <MessageId>
      <xsl:value-of select="." />
    </MessageId>
  </xsl:template>

  <xsl:template match="text()" />
</xsl:stylesheet>

1 Comment

but what if I have more complex XML? Like this: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <ns2:completeProductionPlan xmlns="http://ServiceManagement/OIS_Services_v01.00/common" xmlns:ns2="http://ServiceManagement/types"> <ns2:messageID> <value>9133235059913398501_9133235059913398860</value> </ns2:messageID> <entityKey> <keyA>9c4332b3-e60d-466b-9ab8-1187e98582e9</keyA> </entityKey> <state> <value>readyForCompletion</value> </state> </ns2:productionPlan> </ns2:completeProductionPlan> </soapenv:Body> </soapenv:Envelope>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.