XSLT:添加新元素时排除命名空间

时间:2014-01-06 10:10:19

标签: xml xslt xalan

我需要使用xalan redirect扩展将新元素添加到现有的xml文件中,但是我的命名空间有问题。

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>

我得到下一个输出:

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

但我需要没有指定名称空间的所有元素,例如<product name="camera">..etc..</product> 任何建议将不胜感激

1 个答案:

答案 0 :(得分:5)

你有

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

以便模板复制命名空间中的t:subcategory元素,然后在无命名空间内创建product元素。这样,结果树的序列化程序需要添加<product xmlns="">以确保元素序列化为已创建。如果要在与product元素相同的命名空间中创建subcategory元素,请确保您拥有

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

在样式表的根元素上(放置在该命名空间中创建的所有元素)或使用

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

或只是文字

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

当然,当您创建其他元素同样适用于它们时,如果您按照第二个建议进行操作,则需要例如: <xsl:element name="provider" namespace="http://www.products.com">也是如此。但是在样式表的根元素上使用文字结果元素甚至是正确的默认命名空间可以更容易。