Question

i need to add a new element into existing xml file using xalan redirect extension, but i have a problem with namespaces.

my xslt : 
<xsl:stylesheet version="1.0"
    xmlns:redirect="http://xml.apache.org/xalan/redirect"
    extension-element-prefixes="redirect" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:validator="xalan://com.epam.app.transformation.Validator"
    xmlns:t="http://www.products.com" exclude-result-prefixes="#default t">
    <xsl:import href="addProductPage.xsl" />
    <xsl:param name="name"></xsl:param>
    <xsl:param name="provider"></xsl:param>
    <xsl:param name="model"></xsl:param>
    <xsl:param name="color"></xsl:param>
    <xsl:param name="dateOfIssue"></xsl:param>
    <xsl:param name="notInStock"></xsl:param>
    <xsl:param name="price"></xsl:param>
    <xsl:param name="filename"></xsl:param>
    <xsl:param name="isValid"
        select="validator:validateFields($name, $provider, $model, $dateOfIssue, $color,$price,$notInStock)" />
    <xsl:param name="categoryName"></xsl:param>
    <xsl:param name="subcategoryName"></xsl:param>

    <xsl:output omit-xml-declaration="yes" indent="no" />
    <xsl:template match="/" priority="2">
        <html>
            <head>
                <title>Products Home Page</title>
            </head>
            <body>
                <xsl:choose>
                    <xsl:when test="$isValid">
                        <redirect:write select="$filename" append="false">

                            <xsl:call-template name="saveProduct" />
                        </redirect:write>
                        <xsl:call-template name="returnToProducts" />
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:call-template name="addProduct" />
                                            <!-- i show errors in here -->
                    </xsl:otherwise>
                </xsl:choose>
            </body>
        </html>
    </xsl:template>
    <xsl:template name="saveProduct" match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
    <xsl:template
        match="/t:categories/t:category[@name=$categoryName]/t:subcategory[@name=$subcategoryName]">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <xsl:element name="product">
                <xsl:attribute name="name">
                <xsl:value-of select="$name" />
                </xsl:attribute>
                <xsl:element name="provider">
                    <xsl:value-of select="$provider" />
                </xsl:element>
                <xsl:element name="model">
                    <xsl:value-of select="$model" />
                </xsl:element>
                <xsl:element name="color">
                    <xsl:value-of select="$color" />
                </xsl:element>
                <xsl:element name="dateOfIssue">
                    <xsl:value-of select="$dateOfIssue" />
                </xsl:element>
                <xsl:choose>
                    <xsl:when test="$notInStock">
                        <xsl:element name="notInStock" />
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:element name="price">
                            <xsl:value-of select="$price" />
                        </xsl:element>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:element>
        </xsl:copy>
    </xsl:template>

    <xsl:template name="returnToProducts">
        <html>
            <head>
                <meta http-equiv="refresh"
                    content="0;url=controller?command=GetProductsCmd&amp;categoryName={$categoryName}&amp;subcategoryName={$subcategoryName}" />
            </head>
        </html>
    </xsl:template>
</xsl:stylesheet>

i get next ouput:

<product xmlns="" name="camera"><provider>pro</provider><model>AB200</model><color>black</color><dateOfIssue>06-01-2014</dateOfIssue><price>1000</price></product>

but i need all elements without specified namespace like this <product name="camera">..etc..</product> any suggestions would be appreciated

Was it helpful?

Solution

You have

<xsl:template
        match="/t:categories/t:category[@name=$categoryName]/t:subcategory[@name=$subcategoryName]">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <xsl:element name="product">

so that template copies the t:subcategory element which is in a namespace but then creates a product element inside in no namespace. That way the serializer of the result tree needs to add <product xmlns=""> to make sure the element is serialized as created. If you want to create the product element in the same namespace as the subcategory element then make sure you either have

<xsl:stylesheet xmlns="http://www.products.com" ...>

on the root element of your stylesheet (to put all elements created in that namespace) or use

<xsl:element name="product" namespace="http://www.products.com">...</xsl:element>

or simply a literal

<product xmlns="http://www.products.com">...</product>

Of course as you create other elements as well the same applies to them, if you go by the second suggestion you need e.g. <xsl:element name="provider" namespace="http://www.products.com"> as well. But using literal result elements or even the right default namespace on the root element of the stylesheet makes it easier.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top