Syspect
Syspect

Reputation: 921

Retrieving XSLT code as string - "Illegal characters in path"

I want to transform a XML document. My XSLT code is working and it transform correctly (tested in XMLPad), but now I want to make it transformed in my VB.NET program. The thing is that I don't want to load the XSLT code from .xsl file. I have it hard-coded in a function, but I am getting Illegal characters in path exception.

Is it possible to have it like that:

Public Class xsltTransformCode
    Public Function transformationXSLTcode() As String
        Return "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>" &
        "<xsl:strip-space elements='*'/>" &
        "<xsl:output method='xml' indent='yes'/>" &
        "<xsl:key name='AreaByPosition' match='Area' use='Position'/>" &
        "<xsl:template match='@*|node()'>" &
            "<xsl:copy><xsl:apply-templates select='@*|node()'/></xsl:copy>" &
          "</xsl:template>" &
            "<!-- for the first Area in each Position -->" &
          "<xsl:template match='Area[generate-id() = generate-id(key('AreaByPosition', Position)[1])]'>" &
            "<Area>" &
              "<!-- copy in the Position element once only -->" &
              "<xsl:apply-templates select='Position'/>" &
              "<!-- copy in all sub-elements except Position from all matching Areas -->" &
              "<xsl:apply-templates select='key('AreaByPosition', Position)/*[not(self::Position)]'/>" &
            "</Area>" &
          "</xsl:template>" &
            "<!-- ignore all other Area elements -->" &
          "<xsl:template match='Area'/>" &
        "</xsl:stylesheet>"
    End Function
End Class

because I get the exception when I try to load it

Dim xsltTransformerCode As New xsltTransformCode()
Dim xsltTransCompiled As New XslCompiledTransform()
xsltTransCompiled.Load(xsltTransformerCode.transformationXSLTcode())

Upvotes: 1

Views: 1067

Answers (4)

Mark Rabjohn
Mark Rabjohn

Reputation: 1713

I Just looked on MSDN to confirm by suspicion, and it verifies that you can't pass the actual XML string to the XslCompiledTransform.Load function. The string versions of this require a URI, hence the complaint about "bad characters in path".

You can however load the XML using an XMLReader:

Dim xsltTransformerCode As New xsltTransformCode()
Dim sr as new System.IO.StringReader(xsltTransformerCode.transformationXSLTcode())
Dim xr as XmlReader = XmlReader.Create(sr)
Dim xsltTransCompiled As New XslCompiledTransform()
xsltTransCompiled.Load(xr)

This was hastily converted from some c# code, I'm sure that you can tinker with it if it doesn't work as is.

Mark

Upvotes: 2

hr_117
hr_117

Reputation: 9627

For example following line is not correct escaped:

"<xsl:template match='Area[generate-id() = generate-id(key('AreaByPosition', Position)[1])]'>"  

From xslt point of view you have to use apostrophe and quote as delimiter. If the attribute delimiter is apostrophe you have to use quotation mark as delimiter for const (liek your key name AreaByPosition.

<xsl:template match='Area[generate-id() = generate-id(key("AreaByPosition", Position[1])]'>" 

But this does not work form visual basic point of view. You have to escape the quotation mark. Therefore try:

   "<xsl:template match='Area[generate-id() = generate-id(key(\"AreaByPosition\", Position)[1])]'>"  

But I'm not sure about esacping in visual basic

Upvotes: 0

Borodin
Borodin

Reputation: 126722

You have this match attribute

match='Area[generate-id() = generate-id(key('AreaByPosition', Position)[1])]'

which contains a single-quoted string within a single-quoted string.

Unfortunately you can't do that, and you will have to escape the inner quotes. I'm afraid I don;t know how to do that in VB.

Upvotes: 0

Marc Gravell
Marc Gravell

Reputation: 1062620

Look at the combination of single-quotes for things like:

<xsl:apply-templates select='key('AreaByPosition', Position)/*[not(self::Position)]'/>

I would advise using double quotes for the xml attributes, and single-quotes for literals; since this is part of a VB string, this will involve doubling the double-quotes to escape them, i.e.

"<xsl:apply-templates select=""key('AreaByPosition', Position)/*[not(self::Position)]""/>" &

(multiple locations etc, not just this one line)

Upvotes: 0

Related Questions