Copied to clipboard

Flag this post as spam?

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


  • Craig Taylor 29 posts 69 karma points
    Jan 31, 2011 @ 20:46
    Craig Taylor
    0

    Trying to get child nodes with a particular document type

    I'm having some issues getting some XPath to work in my C# code.


    I'm correctly getting reference to a particular node using:

    XmlDocument umbracoXml = umbraco.content.Instance.XmlContent;
    umbracoXml.SelectNodes(string.Format("root/descendant-or-self::*[@id={0}]", myNode.Id))

    This part works great, but now I need to get all child nodes under this node that have a particular document type.  There will be any number of levels under this node, so they won't be direct children.  For this particular example, the tree looks like this:

    myNode

    ---------- Child Node

    -------------------Child Node of Child Node

    --------------------------------- The node I'm trying to select

    I've tried:

    umbracoXml.SelectNodes(string.Format("root/descendant-or-self::*[@id={0}]/descendant::node[@nodeTypeAlias='MyDocumentType']", myNode.Id))

    , but it doesn't work.  Can anyone steer me in the right direction?

    Thanks!
    Craig

     

  • Jan Skovgaard 11280 posts 23678 karma points MVP 10x admin c-trib
    Jan 31, 2011 @ 20:57
    Jan Skovgaard
    0

    Hi Craig

    Do you get some kind of error when you try to execute the code?

    /Jan

  • Craig Taylor 29 posts 69 karma points
    Jan 31, 2011 @ 21:00
    Craig Taylor
    0

    Hi Jan.

    No, no errors.  I'm just getting zero nodes returned when I am expecting one.  Later, I will be expecting many more results as I get client content into Umbraco.  If the xpath looks okay, maybe I just have something else configured incorrectly on my nodes. . .

    Thanks!
    Craig

  • Kim Andersen 1447 posts 2196 karma points MVP
    Jan 31, 2011 @ 21:22
    Kim Andersen
    1

    What I would do in XSLT (though), was something like this:

    $currentPage/descendant-or-self::MyDocumentType

    the above code would work with the "new" XML schema. I can see that you are trying to find a node with a nodeTypeAlias of "MyDocumentType" <-- This will only work if you are using the legacy XML schema.

    /Kim A

  • Craig Taylor 29 posts 69 karma points
    Jan 31, 2011 @ 21:27
    Craig Taylor
    0

    Hi Kim.  

    Perhaps using code to work with legacy schema is my issue.  I wasn't aware of the changes.  (I'm using 4.5.2)  I'll investigate the nuances of the 'new' schema and see what I'm doing wrong.  I still welcome replies, however. :)

    Thanks everyone!
    Craig

  • Jan Skovgaard 11280 posts 23678 karma points MVP 10x admin c-trib
    Jan 31, 2011 @ 21:43
    Jan Skovgaard
    1

    Hi Craig

    I think the most easy way to get an idea of the new schema is to have a look at the umbraco.config file. And I think Kim's answer is the solution btw :-)

    /Jan

  • Kim Andersen 1447 posts 2196 karma points MVP
    Jan 31, 2011 @ 22:21
    Kim Andersen
    2

    Craig, just a quick explanation on what the difference between the legacy schema and the new one is in your case something like this:

    The legacy schema:

    <root>
    <node id="xxxx" nodeTypeAlias="HomePage">
    ...
    <node id="xxxx" nodeTypeAlias="TextPage">
    <data alias="content">some content</data>
    ...
    </node>
    <node id="xxxx" nodeTypeAlias="TextPage">
    <data alias="content">some content</data>
    ...
    </node>
    </node>
    </root>

    The "new" schema:

    <root>
    <HomePage id="xxxx" isDoc="">
    ...
    <TextPage id="xxxx" isDoc="">
    <content>some content</content>
    ...
    </TextPage>
    <TextPage id="xxxx" isDoc="">
    <content>some content</content>
    ...
    </TextPage>
    </HomePage>
    </root>

    As you can see the nodeTypeAlias-attribute are gone, and the node's name are now called what was in the nodeTypeAlias before - the alias of the document type that is.

    /Kim A

  • Craig Taylor 29 posts 69 karma points
    Feb 01, 2011 @ 15:18
    Craig Taylor
    0

    Awesome guys!  Jan, your solution works great!  I'm now getting the correct nodes.

    Kim, thanks for explaining the new XML schema, this helps me understand the structure more.  The schema changed in 4.1, right?

    -Craig

  • Kim Andersen 1447 posts 2196 karma points MVP
    Feb 01, 2011 @ 15:39
    Kim Andersen
    0

    No problem Craig.

    Well, yes the XML schema changed in v4.1, but actually v4.1 is v4.5. But yeah you could say that it changed in v4.1 :)

    /Kim A

  • Mysterious 20 posts 40 karma points
    Feb 01, 2011 @ 21:26
    Mysterious
    0

    Hello,

    I have the same question but I don't really get the answer, could you please put a complete xslt sample of how I would get the children and grand children of the required node?

    here is the situation I am talking about:

    Products
    ----->Cat 1
    ---------------->Product 1
    ---------------->Product 2
    ---------------->Product 3
    ----->Cat 2
    ---------------->Product 1
    ----->Cat 3
    ---------------->Product 1
    ---------------->Product 2

    thank you

  • Jan Skovgaard 11280 posts 23678 karma points MVP 10x admin c-trib
    Feb 01, 2011 @ 21:28
    Jan Skovgaard
    0

    Hi Mysterious

    Actually what you're trying to achieve is something that you can see an example of by choosing the "Sitemap" XSLT snippet when you create a XSLT macro in the developer section.

    It recursively travles through all the nodes beneath the starting node, which can be set in a variable in the XSLT if I remember correctly. You can also define how many levels should be shown.

    Try having a look at it as a starting point :-)

    Hope this helps.

    /Jan

  • Craig Taylor 29 posts 69 karma points
    Feb 01, 2011 @ 21:37
    Craig Taylor
    0

    Kim:

    Gotcha, XML Schema version 4.1, Umbraco version 4.5.

    Thanks!
    Craig

  • Mysterious 20 posts 40 karma points
    Feb 01, 2011 @ 21:48
    Mysterious
    0

    Ok thank you for quick reply,

    but I am new to xslt

    I guess the line you are pointing to is:
    <xsl:with-param name="parent" select="$currentPage/ancestor-or-self::* [@isDoc and @level=1]"/>

    so I don't want "*" instead I want the master node to be "Products"
    <xsl:with-param name="parent" select="$currentPage/ancestor-or-self::Products [@isDoc and @level=1]"/>

    when I try to save I get the following error:

    "

    Error occured

    System.OverflowException: Value was either too large or too small for an Int32. 
    at System.Convert.ToInt32(Double value) 
    at System.Double.System.IConvertible.ToInt32(IFormatProvider provider) 
    at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) 
    at System.Xml.Xsl.Runtime.XmlQueryRuntime.ChangeTypeXsltArgument(XmlQueryType xmlType, Object value, Type destinationType) 
    at System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(String name, String namespaceUri, IList`1[] args) 
    at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, IList`1 parent) 
    at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime) 
    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) 
    at System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, XmlWriter results, XmlResolver documentResolver) 
    at System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, TextWriter results) 
    at umbraco.presentation.webservices.codeEditorSave.SaveXslt(String fileName, String oldName, String fileContents, Boolean ignoreDebugging)"

     

    can you help figuring out the issue?

     

  • Jan Skovgaard 11280 posts 23678 karma points MVP 10x admin c-trib
    Feb 01, 2011 @ 21:59
    Jan Skovgaard
    0

    Hi Mysterious

    What happens if you check the "skip error checking" when you save the XSLT? Does it display properly then?

    Otherwise please post the XSLT you're working on so it's possible for us to see the changes you have made :-)

    /Jan

  • Mysterious 20 posts 40 karma points
    Feb 01, 2011 @ 22:14
    Mysterious
    0

    Actually no, I got the following error in the page that contains the macro:

    Error parsing XSLT file: \xslt\Sitemap.xslt

    the xslt file is the sitemap.xslt which is generated by umbraco:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
    <xsl:stylesheet 
      version="1.0" 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
      xmlns:msxml="urn:schemas-microsoft-com:xslt" 
      xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" xmlns:tagsLib="urn:tagsLib" xmlns:BlogLibrary="urn:BlogLibrary" 
      exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets tagsLib BlogLibrary ">

      
    <xsl:output method="xml" omit-xml-declaration="yes"/>

    <xsl:param name="currentPage"/>

    <!-- update this variable on how deep your site map should be -->
    <xsl:variable name="maxLevelForSitemap" select="4"/>

    <xsl:template match="/">
    <div id="sitemap"> 
    <xsl:call-template name="drawNodes">  
      <xsl:with-param name="parent" select="$currentPage/ancestor-or-self::Products [@isDoc and @level=1]"/>
    </xsl:call-template>
    </div>
    </xsl:template>

    <xsl:template name="drawNodes">
    <xsl:param name="parent"/> 
    <xsl:if test="umbraco.library:IsProtected($parent/@id, $parent/@path) = 0 or (umbraco.library:IsProtected($parent/@id, $parent/@path) = 1 and umbraco.library:IsLoggedOn() = 1)">
    <ul><xsl:for-each select="$parent/* [@isDoc and string(umbracoNaviHide) != '1' and @level &lt;= $maxLevelForSitemap]"> 
    <li>  
    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:value-of select="@nodeName"/></a>  
    <xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1' and @level &lt;= $maxLevelForSitemap]) &gt; 0">   
    <xsl:call-template name="drawNodes">    
    <xsl:with-param name="parent" select="."/>    
    </xsl:call-template>  
    </xsl:if> 
    </li>
    </xsl:for-each>
    </ul>
    </xsl:if>
    </xsl:template>
    </xsl:stylesheet>

     

    I only modified the following line:

      <xsl:with-param name="parent" select="$currentPage/ancestor-or-self::* [@isDoc and @level=1]"/>

    to:

      <xsl:with-param name="parent" select="$currentPage/ancestor-or-self::Products [@isDoc and @level=1]"/>

     

    Thank you for your time

  • Jan Skovgaard 11280 posts 23678 karma points MVP 10x admin c-trib
    Feb 01, 2011 @ 22:28
    Jan Skovgaard
    1

    Hi again

    Try altering this

      <xsl:with-param name="parent" select="$currentPage/ancestor-or-self::Products [@isDoc and @level=1]"/>

    To

      <xsl:with-param name="parent" select="$currentPage/ancestor-or-self::Products [@isDoc]"/>

    Does this help? I'm thinking that the Products document type does not exist on level 1, right?

    /Jan

  • Mysterious 20 posts 40 karma points
    Feb 01, 2011 @ 22:41
    Mysterious
    0

    Once again you help me out with my problems...

    Thank you very much
    Mysterious

  • Jan Skovgaard 11280 posts 23678 karma points MVP 10x admin c-trib
    Feb 01, 2011 @ 22:43
    Jan Skovgaard
    0

    Hi Mysterious

    You're welcome. Happy to hear it worked. Hope you're enjoying to work with Umbraco. If you run into something that does not make sense you know where to ask :-)

    /Jan

Please Sign in or register to post replies

Write your reply to:

Draft