Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Lee 1130 posts 3088 karma points
    Jan 13, 2010 @ 12:03
    Lee
    0

    Has Anyone Actually Got GetXmlNodeByXPath Working?

    Just curious, as whenever I try and use it - It never ever works??? Simple example below based on the Wiki example (Still won't work?) - Here is the Xpath I want to use

      <xsl:variable name="myxpath">
        <xsl:choose>
          <xsl:when test="string($thesearch) != ''">
            <xsl:text>umbraco.library:GetXmlNodeById('1105')/descendant::node [@nodeTypeAlias = $documentTypeAlias and contains(./@nodeName, $thesearch)]</xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text>umbraco.library:GetXmlNodeById('1105')/descendant::node [@nodeTypeAlias = $documentTypeAlias]</xsl:text>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>

    And here is how I use it (Based on this Wiki entry > http://our.umbraco.org/wiki/reference/umbracolibrary/getxmlnodebyxpath)

    <xsl:for-each select="umbraco.library:GetXmlNodeByXPath($myxpath)">

    Error I get

    Error parsing the XSLT:

    System.Xml.Xsl.XslTransformException: An error occurred during a call to extension function 'GetXmlNodeByXPath'. See InnerException for a complete description of the error. ---> System.Xml.XPath.XPathException: Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-defined function. at MS.Internal.Xml.XPath.CompiledXpathExpr.get_QueryTree() at System.Xml.XPath.XPathNavigator.Evaluate(XPathExpression expr, XPathNodeIterator context) at System.Xml.XPath.XPathNavigator.Evaluate(XPathExpression expr) at System.Xml.XPath.XPathNavigator.Select(XPathExpression expr) at System.Xml.XPath.XPathNavigator.Select(String xpath) at umbraco.library.GetXmlNodeByXPath(String xpathQuery) --- End of inner exception stack trace --- at System.Xml.Xsl.Runtime.XmlExtensionFunction.Invoke(Object extObj, Object[] args) at System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(String name, String namespaceUri, IList`1[] args) at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current) at Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime) at Execute(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime) at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlSequenceWriter results) at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter) at System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results) at System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, TextWriter results) at System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, TextWriter results) at umbraco.macro.GetXsltTransformResult(XmlDocument macroXML, XslCompiledTransform xslt, Dictionary`2 parameters) at umbraco.presentation.umbraco.developer.Xslt.xsltVisualize.visualizeDo_Click(Object sender, EventArgs e)

    Now I can get round this using a custom C# function that Doug sorted out, but I just want to know why I can't use this built in method?  What am I doing wrong??

  • Lee Kelleher 4026 posts 15836 karma points MVP 13x admin c-trib
    Jan 13, 2010 @ 12:21
    Lee Kelleher
    0

    Hi Lee,

    That error is because you are using a namespace-prefix/extension (i.e. umbraco.library), in the XPath query you are passing to the GetXmlNodeByXPath() method.

    GetXmlNodeByXPath() doesn't load in any XSLT extensions, so you are limited to pure XPath 1.0 syntax.

    You probably don't need GetXmlNodeByXPath() at all, since you could just stick with GetXmlNodeById:

    <xsl:variable name="node" select="umbraco.library:GetXmlNodeById('1105')" />

    Hope that helps? (a little)

    Cheers, Lee.

  • Lee 1130 posts 3088 karma points
    Jan 13, 2010 @ 12:52
    Lee
    0

    Ahhhh I'm with you!  Awesome I'll give it a crack now..  Yet another Guinness I owe you ;)

  • Lee 1130 posts 3088 karma points
    Jan 13, 2010 @ 14:52
    Lee
    0

    Just to go back to this, I shouldn't have marked it as solved - I meant to give Lee a thumbs up (But you can't remove it once its been marked!!)

    Anyway...  This GetXmlNodeById just doesn't work!  I have changed it to full xpath like so

      <xsl:variable name="myxpath">
        <xsl:choose>
          <xsl:when test="string($thesearch) != ''">
            <xsl:text>$currentPage/ancestor-or-self::node/descendant::node [@nodeTypeAlias = $documentTypeAlias and contains(./@nodeName, $thesearch)]</xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text>$currentPage/ancestor-or-self::node/descendant::node [@nodeTypeAlias = $documentTypeAlias]</xsl:text>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>
    
    <xsl:for-each select="umbraco.library:GetXmlNodeByXPath($myxpath)">

    Still this doesn't work, get the following error???  Man how anyone can say using XSLT is better than .NET I'll never know :(

     

  • Lee 1130 posts 3088 karma points
    Jan 13, 2010 @ 14:53
    Lee
    0

    Damn that should read

    This GetXmlNodeByXPath just doesn't work!  I have changed it to full xpath like so (No edit button lol)

  • Lee 1130 posts 3088 karma points
    Jan 13, 2010 @ 14:55
    Lee
    0

    Sorry... The error is exactly the same as the top one :(

     

  • Stefan Kip 1614 posts 4131 karma points c-trib
    Jan 13, 2010 @ 15:15
    Stefan Kip
    0

    I haven't used it before, but I have a wild guess:

    contains(./@nodeName, $thesearch)] --> that's a function right?

  • Lee Kelleher 4026 posts 15836 karma points MVP 13x admin c-trib
    Jan 13, 2010 @ 15:52
    Lee Kelleher
    0

    Lee, sorry that it's frustrating you... it will all make sense at some point (honest, I hope).

    The problem with your revised xpath is that it's got "$currentPage" in there now.  Again, the GetNodeByXPath() has no context of $currentPage (same as the XSLT extensions) - so throws the error.

    I do think what you are after ... and a few other people would find useful - is a node-set filter ... so you can pass in a node-set and an XPath query, and get back what you need.  I think this is what Doug showed you last time - but would be good if it was available in umbraco.library.

    Cheers, (the other) Lee

  • Lee 1130 posts 3088 karma points
    Jan 13, 2010 @ 16:24
    Lee
    1

    Hey Lee - Don't apologise dude, you have been a great help :)

    I did blog the function Doug and his wife sorted for me (http://www.blogfodder.co.uk/post/Building-Up-A-String-XPath-Statement-In-XSLT.aspx) but as that function was there I was determined to get the bloody thing to work for my own sanity! (But failed so far ... lol)

    I have left it for the mo, and will attack it tomorrow with a fresh head :)

  • Stefan Kip 1614 posts 4131 karma points c-trib
    Jan 13, 2010 @ 17:46
    Stefan Kip
    0

    Just make life easier, use LINQ!

    Hehe, sorry, I'm a .NET / LINQ addict :P

  • Lee 1130 posts 3088 karma points
    Jan 13, 2010 @ 20:20
    Lee
    0

    To be honest I have been looking into that, I started to watch aarons screen casts and signed up for TekPub - Where Justin Etheridge has started a Linq series :)

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Jan 13, 2010 @ 20:45
    Chriztian Steinmeier
    0

    Hi Lee,

    I've got a yet-to-be-released upcoming version of XML Dump with a crude implementation of an 'xpath' option that uses the GetXmlNodeByXPath() function - so, yes, I have actually been able to get that darned function working :-)

    /Chriztian 

  • Jesper Hauge 298 posts 487 karma points c-trib
    Jan 14, 2010 @ 09:52
    Jesper Hauge
    1

    Hi Lee

    The GetXmlNodeByXpath acutally runs an xpath query on the root of the umbraco xml content (umbraco.config), so you cannot pass variable name in your xpath statement, since the transformation done by GetXmlNodeByXPath has no access to the values in these variables when running the query.

    So you need to output the values of your variables into the xpath string you're building, and do away with the $currentPage

    In the code below I've replaced the GetXmlNodeById with the "//descendant::node[@id='1105']" which finds any descendant below the root node with id=1105, and I've concatenated the variable values into the xpath variable:

    <xsl:variable name="myxpath">
        <xsl:choose>
            <xsl:when test="string($thesearch) != ''">
                <xsl:text>//descendant::node[@id='1105']/descendant::node[@nodeTypeAlias='</xsl:text>
                <xsl:value-of select="string($documentTypeAlias)" />
                <xsl:text>' and contains(./@nodeName, '</xsl:text>
                <xsl:value-of select="string($thesearch)" />
                <xsl:text>')]</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>//descendant::node[@id='1105']/descendant::node[@nodeTypeAlias='</xsl:text>
                <xsl:value-of select="string($documentTypeAlias)" />
                <xsl:text>']</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    

    That should do the trick, but you might want to check that your xpath statement actually is correct, by outputting it to your code with a

    <xsl:copy-of select="$myxpath" />

    Before inserting it into the GetXmlNodeByXPath method.

    Regards
    Jesper Hauge

  • Jesper Hauge 298 posts 487 karma points c-trib
    Jan 14, 2010 @ 10:06
    Jesper Hauge
    0

    Hi again

    Just had to append this:

    I think you're making it harder to solve the problem by using GetXmlNodeByXPath here, if you just want a node set from the xpath you were building, I think this would be simpler:

    <xsl:variable name="documentType" select="'textPage'" />
    <xsl:variable name="theSearch" select="'mystring'" />
    <xsl:variable name="resultNodes">
        <xsl:choose>
            <xsl:when test="string($theSearch) != ''">
                <xsl:copy-of select="umbraco.library:GetXmlNodeById('1105')/descendant::node[@nodeTypeAlias=$documentType and contains(./@nodeName, $theSearch)]" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy-of select="umbraco.library:GetXmlNodeById('1105')/descendant::node[@nodeTypeAlias=$documentType]" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

    Regards
    Jesper Hauge

Please Sign in or register to post replies

Write your reply to:

Draft