如何在Kentico中解析多级XML?Universal Viewer/Repeater调用咨询
Hey there, let's work through this XML data issue in Kentico together! The core problem here is that the default XML Data Source doesn't automatically traverse nested nodes like <users> out of the box, but there are a few solid ways to fix this and get your user data into a Repeater or Universal Viewer.
方案1:调整XML Data Source的XPath表达式
The simplest fix is to explicitly target the user nodes with an XPath expression. Let's say your XML structure looks something like this:
<root> <users> <user> <username>clintw</username> <email>clint@example.com</email> </user> <user> <username>johnd</username> <email>john@example.com</email> </user> </users> </root>
In the Kentico backend, when configuring your XML Data Source:
- Find the XPath expression setting field
- Enter a path that directly points to your user nodes, e.g.,
/root/users/user
This tells the data source to skip the parent <users> node and pull each individual <user> entry instead. Once configured, you can bind this data source to a Repeater or Universal Viewer, and use transformations like <%# Eval("username") %> to display the user fields.
方案2:用自定义代码手动解析XML并绑定
If XPath isn't cutting it (maybe your XML has complex namespaces or irregular structure), you can build a simple ASCX user control to handle the parsing manually, then bind the data to a Repeater. Here's a quick example:
Backend code (ASCX.cs)
protected void Page_Load(object sender, EventArgs e) { // Load XML - replace this with your Web service's XML string/file path XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(YourWebService.GetXmlResponse()); // Or use xmlDoc.Load(Server.MapPath("~/path/to/file.xml")) // Grab all user nodes (adjust XPath if your structure differs) XmlNodeList userNodes = xmlDoc.SelectNodes("//users/user"); // Convert to a bindable list List<UserRecord> users = new List<UserRecord>(); foreach (XmlNode node in userNodes) { users.Add(new UserRecord { Username = node.SelectSingleNode("username")?.InnerText ?? "", Email = node.SelectSingleNode("email")?.InnerText ?? "" }); } // Bind to Repeater rptUserList.DataSource = users; rptUserList.DataBind(); } // Simple class to hold user data public class UserRecord { public string Username { get; set; } public string Email { get; set; } }
Frontend markup (ASCX)
<asp:Repeater ID="rptUserList" runat="server"> <ItemTemplate> <div class="user-card"> <h4><%# Eval("Username") %></h4> <p>Email: <%# Eval("Email") %></p> </div> </ItemTemplate> </asp:Repeater>
Just add this control to your Kentico page, and it'll render the user data directly. This approach gives you full control over XML parsing, perfect for edge cases.
方案3:Universal Viewer with Custom Data Source
If you prefer using the Universal Viewer, you can create a custom data source to feed it parsed user data:
- Go to Development > Data sources in the Kentico backend
- Create a new Custom Data Source
- In the code section, implement the
IEnumerableinterface to return your parsed user list (similar to the logic in方案2) - Save the data source, then add a Universal Viewer to your page and select this custom source
- Configure a transformation to display the user fields as needed
Quick Notes to Avoid Headaches
- Double-check that your XML is well-formed (no missing tags or syntax errors)
- If your XML uses namespaces, you'll need to add a namespace manager to your XPath queries, e.g.:
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmlDoc.NameTable); nsMgr.AddNamespace("ns", "http://your-xml-namespace.com"); XmlNodeList userNodes = xmlDoc.SelectNodes("//ns:users/ns:user", nsMgr);
内容的提问来源于stack exchange,提问作者Clint Warner

