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
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. . .
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.
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. :)
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 :-)
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.
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?
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.
I guess the line you are pointing to is: <xsl:with-paramname="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-paramname="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)"
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 :-)
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:
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:
, but it doesn't work. Can anyone steer me in the right direction?
Thanks!
Craig
Hi Craig
Do you get some kind of error when you try to execute the code?
/Jan
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
What I would do in XSLT (though), was something like this:
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
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
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
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:
The "new" schema:
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
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
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
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
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
Kim:
Gotcha, XML Schema version 4.1, Umbraco version 4.5.
Thanks!
Craig
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?
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
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 " "> ]>
<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 <= $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 <= $maxLevelForSitemap]) > 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
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
Once again you help me out with my problems...
Thank you very much
Mysterious
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
is working on a reply...