0

I have the following test code that tries to convert a cvs file to xml. The problem I have is that sometimes it will run and other times it fails with the following error:

The specified node cannot be inserted as the valid child of this node, because the specified node is the wrong type.

Here is the code:

        XsltCompiler compiler = null;
        try
        {
            Processor processor = new Processor();
            compiler = processor.NewXsltCompiler();

            var sr = new StreamReader(@"c:\files\drop\csv-to-xml_v2.xslt");
            var xslt = sr.ReadToEnd();
            sr.Close();

            StringReader reader = new StringReader(xslt);

            XsltExecutable exec = compiler.Compile(reader);

            XsltTransformer transformer = exec.Load();

            transformer.InitialTemplate = new QName("", "main");

            var XmlResult = new DomDestination();

            transformer.Run(XmlResult);

            reader.Close();
        }
        catch (Exception ex)
        {
            var errMsg = ex.Message;
            var errList = compiler != null ? compiler.ErrorList : null;
        }

The XSLT is:

<?xml version="1.0"?>

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="fn"
exclude-result-prefixes="xs fn">

<xsl:output indent="yes" encoding="US-ASCII"/>

<xsl:param name="pathToCSV" select="'file:///C:/Files/Drop/inputcsv1.csv'"/>

<xsl:function name="fn:getTokens" as="xs:string+">
<xsl:param name="str" as="xs:string"/>
    <xsl:analyze-string select="concat($str, ',')" regex='(("[^"]*")+|[^,]*),'>
        <xsl:matching-substring>
            <xsl:sequence select='replace(regex-group(1), "^""|""$|("")""", "$1")'/>
        </xsl:matching-substring>
    </xsl:analyze-string>
</xsl:function>

<xsl:template match="/" name="main">
<xsl:choose>
    <xsl:when test="unparsed-text-available($pathToCSV)">
        <xsl:variable name="csv" select="unparsed-text($pathToCSV)"/>
        <xsl:variable name="lines" select="tokenize($csv, '&#xD;')" as="xs:string+"/>
        <xsl:variable name="elemNames" select="fn:getTokens($lines[1])" as="xs:string+"/>
        <root>
            <xsl:for-each select="$lines[position() > 0]">
                <row>
                    <xsl:variable name="lineItems" select="fn:getTokens(.)" as="xs:string+"/>

                    <xsl:for-each select="$elemNames">
                        <xsl:variable name="pos" select="position()"/>
                        <column>
                            <xsl:value-of select="$lineItems[$pos]"/>
                        </column>
                    </xsl:for-each>
                </row>
            </xsl:for-each>
        </root>
    </xsl:when>
    <xsl:otherwise>
        <xsl:text>Cannot locate : </xsl:text><xsl:value-of select="$pathToCSV"/>
    </xsl:otherwise>
</xsl:choose>
</xsl:template>

</xsl:stylesheet>

Can anyone see why sometimes it works and then for no reason it fails on the "transformer.Run(XmlResult)" line ? I am using c# 4, Visual Studio 2010 and Saxon 9 HE.

1 Answer 1

1

In the "otherwise" branch, you are creating a text node as a child of the document node. Because your destination is a DOM destination, this isn't allowed. (It's permitted in the XDM data model, but there is no way of representing this in a DOM).

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

Comments

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.