Reputation: 759
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&categoryName={$categoryName}&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
Upvotes: 0
Views: 3888
Reputation: 167716
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.
Upvotes: 6