/ / ¿Cómo puedo convertir la salida de asp: SiteMapPath en una lista? - .net, vb.net

¿Cómo puedo convertir la salida de asp: SiteMapPath en una lista? - .net, vb.net

No estoy muy familiarizado con ambos .NET y VB.NET y no sé cómo hacerlo. Di que tengo un código como este:

<div class="breadcrumb">
<asp:SiteMapPath ID="SiteMapPath1" runat="server"></asp:SiteMapPath>
</div>

Se produce un montón de <span>s con > Como separadores, algo como esto:

<div class="breadcrumb">
<span id="ctl00_SiteMapPath1">
<a href="#ctl00_SiteMapPath1_SkipLink">
<img alt="Skip Navigation Links" height="0" width="0" src="/images//Bonfield/WebResource.axd?d=PEpmmIw6qvhaEC3hEwXGjgvJKlzc3DOMu_e-zW-n6pfl6YR-iYjwmlvrYPb689EslKxysA7aoh_x_ALjLs5QXiz7NG41&amp;t=634245478914809245" style="border-width:0px;" />
</a>
<span>
<a href="/Bonfield/Default.aspx">Home</a>
</span>
<span> &#187; </span>
<span>Showcase</span><a id="ctl00_SiteMapPath1_SkipLink"></a></span>
</div>

¿Cómo puedo convertir eso en una lista como:

<ul>
<li>Home</li>
<li>Showcase</li>
</ul>

Respuestas

2 para la respuesta № 1

Puede que haya resuelto esto ahora, pero podría usar esta función para recorrer todos los elementos en el nodo raíz de un mapa del sitio y sus descendientes y crear una lista anidada.

Puedes quitar If item.HasChildNodes Then sb.Append(ListChildNodes(item)) Si solo te interesa el nivel superior.

 Public Function SiteMap() As String
Return ListChildNodes(System.Web.SiteMap.RootNode)
End Function

Private Function ListChildNodes(ByVal node As System.Web.SiteMapNode) As String
Dim sb As New System.Text.StringBuilder

sb.Append("<ul>")
For Each item As SiteMapNode In node.ChildNodes
sb.Append(String.Concat("<li><a href=""", item.Url, """>", item.Title, "</a></li>"))
If item.HasChildNodes Then sb.Append(ListChildNodes(item))
Next
sb.Append("</ul>")

Return sb.ToString
End Function

Para aquellos a quienes les gustaría la versión C #:

public string SiteMap()
{
return ListChildNodes(System.Web.SiteMap.RootNode);
}
private string ListChildNodes(System.Web.SiteMapNode node)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();

sb.Append("<ul>");
foreach (SiteMapNode item in node.ChildNodes)
{
sb.Append(string.Concat("<li><a href="", item.Url, "">", item.Title, "</a></li>"));
if (item.HasChildNodes)
sb.Append(ListChildNodes(item));
}
sb.Append("</ul>");

return sb.ToString();
}

Luego, en su código, simplemente puede llamar para enviar la cadena a la página.

<h1>Site Map</h1>
<%=SiteMap()%>
</div>

2 para la respuesta № 2

Si bien no puede deshacerse de las etiquetas span, PUEDElograr lo que quieres Me encontré con este mismo problema porque estaba usando una plantilla de sitio CSS / HTML comprada que el cliente quería, pero todo estaba basado en <ul>"s y <li>"s. Refactorizar el CSS hubiera sido demasiado doloroso, así que encontré esta solución que funcionó bien sin ningún cambio en el código CSS.

Harás dos cosas:

  1. Reemplace la plantilla de nodo predeterminada con una que use <li> etiquetas
  2. Envuelve todo en una <ul> etiqueta

Aquí hay un ejemplo:

<ul style="list-style-type: none;">
<asp:SiteMapPath ID="SiteMapPath1" runat="server" >
<NodeTemplate>
<li>
<a href="<%# Eval("url") %>" title="<%# Eval("description") %>"><%# Eval("title") %></a>
</li>
</NodeTemplate>
</asp:SiteMapPath>
</ul>

0 para la respuesta № 3

Lo más cercano que puedo pensar es poner tu sitemap en un <asp:menu> controlar. Sin embargo, esto se mostrará como una tabla html, pero visualmente mostrará una lista:

<asp:Menu ID="leftNavigation" runat="server" DataSourceID="SiteMapDataSource1"
StaticDisplayLevels="1" MaximumDynamicDisplayLevels="1">
</asp:Menu>
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="false" />

Juega con todas las opciones de estilo y formato para obtener el resultado deseado. Mira aquí para un tutorial detallado.

Ah, y por supuesto, también podría considerar el uso de una vista de árbol con un mapa del sitio (consulte la misma página).


0 para la respuesta № 4

Aunque está un poco involucrado, esta es una solución que elimina los tramos y genera una lista limpia.

En primer lugar, deshacerse de esos espacios excesivos modificando el SiteMapPath. He derivado una clase NakedSiteMapPath que hace esto Todavía permite el uso de intervalos explícitos en plantillas, si es necesario:

/// <summary>
///     A SiteMapPath, that does not render span elements.
/// </summary>
/// <remarks>
///     To still allow explizit spans inside the node templates, immediately prefix the opening and closing span elements
///     with the literal
///     prefix "<!--KEEP NEXT SPAN-->" (without the double quotes)
///     Example:
///     <code>
///     <PathSeparatorTemplate><!--KEEP NEXT SPAN--><span class="icon icon--greater"><!--KEEP NEXT SPAN--></span>
///         </PathSeparatorTemplate>
/// </code>
///     Those spans (opening and closing) will be kept, but the prefix removed in the rendered output.
/// </remarks>
/// <devdoc>
///     The MSDN doc has a nice example about a customized breadcrumb with a dropdown menu here:
///     https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.sitemappath%28v=vs.110%29.aspx
/// </devdoc>
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
[ToolboxData("<{0}:NakedSiteMapPath runat=server></{0}:NakedSiteMapPath>")]
public class NakedSiteMapPath : SiteMapPath {
/// <summary>
///     Outputs server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter" /> object and stores
///     tracing information about the control if tracing is enabled.
/// </summary>
/// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter" /> object that receives the control content.</param>
public override void RenderControl(HtmlTextWriter writer) {
//Render to a local string, then remove all unnecessary spans
StringBuilder myStringBuilder = new StringBuilder();
TextWriter myTextWriter = new StringWriter(myStringBuilder);
HtmlTextWriter myWriter = new HtmlTextWriter(myTextWriter);
base.RenderControl(myWriter);

string html = myStringBuilder.ToString();

//Remove all spans, except those opening and closing spans wich have been marked with the literal comment "<!--KEEP NEXT SPAN-->"
const string matchOpenExceptSkipPrefix = @"(?<!<!--KEEP NEXT SPAN-->)<span>";
const string matchCloseExceptSkipPrefix = @"(?<!<!--KEEP NEXT SPAN-->)</span>";
html = Regex.Replace(html, matchOpenExceptSkipPrefix, String.Empty);
html = Regex.Replace(html, matchCloseExceptSkipPrefix, String.Empty);
html = html.Replace(@"<!--KEEP NEXT SPAN-->", String.Empty);

//finally, write the naked html out.
writer.Write(html);
}
}

Con eso, los tramos se han ido. Para tener enlaces personalizados, como el li Elementos, tendrá que usar las plantillas, como otros ya han propuesto. Aquí hay un ejemplo de parte de la página ASPX con el NakedSiteMapPath:

<ol class="breadcrumb" role="navigation" aria-labelledby="pagebreadcrumbs">
<my:NakedSiteMapPath runat="server"
PathDirection="RootToCurrent"
RenderCurrentNodeAsLink="False">
<PathSeparatorTemplate><!--KEEP NEXT SPAN--><span class="icon icon--greater"><!--KEEP NEXT SPAN--></span></PathSeparatorTemplate>
<CurrentNodeTemplate>
<li class="active" aria-selected="true">
<asp:Literal
Text="<%# Eval("Title") %>"
runat="server" />
</li>
</CurrentNodeTemplate>
<NodeTemplate>
<li>
<asp:HyperLink
ID="lnkPage"
Text="<%# Eval("Title") %>"
NavigateUrl="<%# Eval("Url") %>"
ToolTip="<%# Eval("Description") %>"
runat="server" />
</li>
</NodeTemplate>
</my:NakedSiteMapPath>
</ol>

-1 para la respuesta № 5

La mejor opción para esto es convertir SiteMapPath para usar Plantillas.

En el <NodeTemplate> puedes colocar <li> Elementos con el formato que necesitas. En el <PathSeparatorTemplate> Puedes colocar el separador.

Envuelve el control SiteMapPath con el <ul> Las etiquetas y eso debería hacerlo.

Ejemplo:

 <ul class="breadcrumb">
<asp:SiteMapPath ID="SiteMapPath1" PathSeparator="" runat="server">
<NodeTemplate>
<li>
<a href="<%# Eval("url") %>" title="<%# Eval("description") %>"><%# Eval("title") %></a>
</li>
</NodeTemplate>
<PathSeparatorTemplate>
<span class="divider">/</span>
</PathSeparatorTemplate>
</asp:SiteMapPath>
</ul>

Esta es una excelente opción cuando se usa Bootstrap y ASP.NET