Question

i have a trouble while trying to save some data to XML using XSLT. So the problem is that everything seems to be ok, no exceptions are thrown, log files are also clean, but I can't see any changes in XML file. And I can't Here is my code for saving output to file

    Transformer transformer = XslTemplatesPool.getTransformer(SAVE_ITEM, realPath);
    setCategoryAndSubcateory(transformer, request);

    String name = request.getParameter(NAME);
    /*retrieving some more parameters*/
    String price = request.getParameter(PRICE);

    transformer.setParameter(NAME, name);
    /*...*/
    transformer.setParameter(XML_PATH, "E:/xslt/WebContent/xml/shop.xml");

    if (price == null) {
        price = "";
    }
    transformer.setParameter(PRICE, price);
    if (notInStock == null) {
        notInStock = "";
    }
    /*
     * out is an instance of PrintWriter
     * PrintWriter out = httpServletResponse.getWriter()
     */
    transformer.setParameter(NOT_IN_STOCK, notInStock);
    executeWrite(out, readWriteLock, transformer);


    protected void executeWrite(PrintWriter out, ReadWriteLock readWriteLock, Transformer transformer) throws HandledException {

    Source xmlSource = new StreamSource("E:/xslt/WebContent/xml/shop.xml");
    StreamResult result = new StreamResult(out);
    Lock writeLock = readWriteLock.writeLock();
    writeLock.lock();

    try {
        transformer.transform(xmlSource, result);
    } catch (TransformerException e) {
        ExceptionHandler.logAndThrow(e, logger);
    } finally {
        writeLock.unlock();
    }
}

From XSLT-generated form addItem (every peace of infomation I need comes nice and smooth at this stage) I retreve some data and try to add it to an xml file using template saveItem

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.example.org/products"
xmlns:redirect="http://xml.apache.org/xalan/redirect"
extension-element-prefixes="redirect"
xmlns:validation="xalan://com.xslt.util.Validator"
exclude-result-prefixes="validation redirect">

<xsl:import href="addItem.xsl" />
<xsl:import href="productsList.xsl" />

<xsl:param name="categoryName" />
<xsl:param name="subcategoryName" />
<xsl:param name="name" />
<xsl:param name="producer" />
<xsl:param name="model" />
<xsl:param name="date-of-issue" />
<xsl:param name="color" />
<xsl:param name="not-in-stock" />
<xsl:param name="price" />
<xsl:param name="xmlPath"/>
<xsl:param name="isValid" select="validation:validate($name, $producer, $model, $date-of-issue, $color, $price, $not-in-stock)" />
<xsl:param name="nameError" select="validation:getNameError()" />
<xsl:param name="producerError" select="validation:getProducerError()" />
<xsl:param name="modelError" select="validation:getModelError()" />
<xsl:param name="dateError" select="validation:getDateError()" />
<xsl:param name="priceError" select="validation:getPriceError()" />
<xsl:param name="colorError" select="validation:getColorError()" />

<xsl:template match="/" priority="2">
    <xsl:choose>
        <xsl:when test="not($isValid)">
            <xsl:call-template name="addItem">
                <xsl:with-param name="nameError" select="$nameError" />
                <xsl:with-param name="producerError" select="$producerError" />
                <xsl:with-param name="modelError" select="$modelError" />
                <xsl:with-param name="dateError" select="$dateError" />
                <xsl:with-param name="priceError" select="$priceError" />
                <xsl:with-param name="colorError" select="$colorError" />
                <xsl:with-param name="not-in-stock" select="$not-in-stock" />
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <redirect:write select="$xmlPath">
                <xsl:call-template name="saveItem" />
            </redirect:write>
            <xsl:call-template name="returnToProducts" />
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="saveItem" match="@*|node()" priority="2">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>

<xsl:template match="/xs:shop/xs:category[@name=$categoryName]/xs:subcategory[@name=$subcategoryName]">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
        <xsl:element name="xs:product">
            <xsl:attribute name="name">
                <xsl:value-of select="$name" />
            </xsl:attribute>
            <xsl:attribute name="producer">
                <xsl:value-of select="$producer" />
            </xsl:attribute>
            <xsl:attribute name="model">
                <xsl:value-of select="$model" />
            </xsl:attribute>
            <xsl:element name="xs:date-of-issue">
                <xsl:value-of select="$date-of-issue" />
            </xsl:element>
            <xsl:element name="xs:color">
                <xsl:value-of select="$color" />
            </xsl:element>
            <xsl:choose>
                <xsl:when test="$not-in-stock">
                    <xsl:element name="xs:not-in-stock" />
                </xsl:when>
                <xsl:otherwise>
                    <xsl:element name="xs: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.do?command=productsList&amp;categoryName={$categoryName}&amp;subcategoryName={$subcategoryName}" />
        </head>
    </html>
</xsl:template>

</xsl:stylesheet>

example of my XML file

<xs:shop xmlns:xs="http://www.example.org/products" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/products shop.xsd">    
<xs:category name="bicycle">
    <xs:subcategory name="frame">
        <xs:product name="Soda FR" producer="NS" model="fr445">
            <xs:date-of-issue>10-05-2012</xs:date-of-issue>
            <xs:color>white</xs:color>
            <xs:price>520$</xs:price>
        </xs:product>
        <xs:product name="Nucleon" producer="Nicolai" model="nc428">
            <xs:date-of-issue>10-05-2012</xs:date-of-issue>
            <xs:color>dark grey</xs:color>
            <xs:not-in-stock/>
        </xs:product>
    </xs:subcategory>
</xs:category>
</xs:shop>
Was it helpful?

Solution

So... Finally I made it. Still there is a small bug

SystemId Unknown; Line #-1; Column #-1; Premature end of file.

but I hope it is one not very difficult to fix.

As you can see below the output stream is now written to StringWriter, and then StringWriter is written to a XML file. Still I can't understand why there is no result (file is just cleared) if you pass a file to StreamResult. May be just my hands growing out of a wrong place. May be I'll make a little research tomorrow.

So, method executeWrite(...) was changed a lot

    protected void executeWrite(PrintWriter out, ReadWriteLock readWriteLock, Transformer transformer)
        throws HandledException {

    Lock readLock = readWriteLock.readLock();
    StringWriter outWriter = new StringWriter();
    Transformer t = null;
    try {
        readLock.lock();
        StreamSource xmlStream = new StreamSource(/*path to XML*/);
        t = transformer;
        t.transform(xmlStream, new StreamResult(outWriter));
    } catch (TransformerException e) {
        ExceptionHandler.logAndThrow(e, logger);
    } finally {
        readLock.unlock();
    }

    Lock writeLock = readWriteLock.writeLock();
    FileWriter fileWriter = null;
    try {
        writeLock.lock();
        fileWriter = new FileWriter(new File(/*path to XML*/));
        fileWriter.write(outWriter.toString());
    } catch (IOException e) {
        ExceptionHandler.logAndThrow(e, logger);
    } finally {
        if (fileWriter != null) {
            try {
                fileWriter.close();
            } catch (IOException e) {
                ExceptionHandler.logAndThrow(e, logger);
            }
        }
        writeLock.unlock();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top