更新原始问题,因为我无法清楚地解释自己,人们专注于XML解析而不是我想要的 - 抱歉
我有一个字符串数组,其中包含如下格式的字符串:
A > A1 > A1-1
A > A1 > A1-2
A > A1 > A1-3
A > A2 > A2-1
A > A2 > A2-2
B > B1 > B1-1
C > C1 > C1-1
字符串实际上代表了这样的类别树:
A
|-- A1
| |-- A1-1
| |-- A1-2
| |-- A1-3
|
|-- A2
| |-- A2-1
| |-- A2-2
B
|-- B1
| |-- B1-1
C
|-- C1
| |-- C1-1
如何将该字符串数组转换为实际包含类别和子类别的集合?我想将该字符串数组转换为 MyCategory对象并将它们放在一个列表中,以便我可以拥有一个产品类别树。
//single category class
public class MyCategory
{
public string Title {get; set;}
public IEnumerable<MyCategory> Children {get; set;}
}
答案 0 :(得分:0)
这里的解析是Example
对于foreach
,您可以像XDocument
那样使用:
var xml = "<root><product><title>Product Title</product><category>A > A1 > A1-1</category></product><product><title>Product Title</product><category>A > A1 > A1-2</category></product><product><title>Product Title</product><category>A > A2 > A2-1</category></product><product><title>Product Title</product><category>B > B1 > B1-1</category></product></root>";
var doc = XDocument.Parse(xml);
var products = doc.Root.Elements("product");
foreach (var product in products)
{
var title = product.Element("title").Value;
var category = product.Element("category").Value;
var categories = category.Replace(" ",string.Empty).Split('>');
Console.WriteLine (categories);
}
输出继电器:
答案 1 :(得分:0)
这是一种做法。
// Single category class
public class MyCategory
{
public string Title { get; set; }
public Dictionary<string, MyCategory> Children { get; set; }
// Constructor
public MyCategory(string title)
{
Title = title;
Children = new Dictionary<string, MyCategory>();
}
}
internal class SO29235482
{
// Dictionary for the root nodes
private readonly Dictionary<string, MyCategory> _categoryTree =
new Dictionary<string, MyCategory>();
public void JustTesting()
{
AddCategoryToTree("A > A1 > A1-1");
AddCategoryToTree("A > A1 > A1-2");
AddCategoryToTree("A > A1 > A1-3");
AddCategoryToTree("A > A2 > A2-1");
AddCategoryToTree("A > A2 > A2-2");
AddCategoryToTree("B > B1 > B1-1");
AddCategoryToTree("C > C1 > C1-1");
if (AddCategoryToTree("C > C1 > C1-1"))
throw new Exception("Incorrect return value for existing entry.");
}
/// <summary>
/// Method to add (if necessary) a category to the category tree. (No input error checking is
/// done - this is simple "proof of concept" code.
/// </summary>
/// <param name="textInput">titles separated by '>', for example "A > A1 > A1-1"</param>
/// <returns>true = category added, false = already in tree</returns>
public bool AddCategoryToTree(string textInput)
{
// Parse the input - no error checking done
string[] titleArray = textInput.Split('>');
// Use recursive method to add the nodes to the tree, if not already there
return AddNodesToTree(titleArray, 0, _categoryTree);
}
/// <summary>
/// Recursive method to process each level in the input string, creating a node if necessary
/// and then calling itself to process the next level.
/// </summary>
private static bool AddNodesToTree(string[] titleArray, int thisIndex,
Dictionary<string, MyCategory> priorDictionary)
{
if (thisIndex >= titleArray.Length)
return false;
bool treeUpdated = false;
// Create node entry in prior Dictionary if not already there
string thisTitle = titleArray[thisIndex].Trim();
MyCategory thisNode;
if (!priorDictionary.TryGetValue(thisTitle, out thisNode))
{
thisNode = new MyCategory(thisTitle);
priorDictionary.Add(thisTitle, thisNode);
treeUpdated = true;
}
// Process the lower-level nodes using this recursive method
return AddNodesToTree(titleArray, ++thisIndex, thisNode.Children) | treeUpdated;
}
}
我用字典&lt;&gt;替换了你的IEnumerable因为那似乎更自然。但它可以重新编码以使用IEnumerable然后执行Find()而不是通过键直接字典查找。
答案 2 :(得分:0)
我用下面的解决方案解决了我的问题。我是如此专注于服务代码的xml部分我自己也看不到实际的问题。 Rennie的回答让我走上了正确的道路。
这是我从“A&gt; A1&gt; A1-1”格式化字符串数组中获取IEnumerable的方法:
private static void RecurseProductCategories(string[] categoryNames, List<Category> parentList, Category parent = null)
{
if (categoryNames.Length > 0)
{
var catName = categoryNames[0].Trim();
var catObject = parentList.SingleOrDefault(f => f.Title == catName);
if (catObject == null)
{
catObject = new Category { Title = catName, Slug = catName.GenerateSlug(), Parent = parent };
parentList.Add(catObject);
}
RecurseProductCategories(categoryNames.Skip(1).ToArray(), catObject.Children, catObject);
}
}
这个递归函数在我这样调用时给了我想要的东西:
string[] demoArray = new string[]
{
"A > A1 > A1-1",
"A > A1 > A1-2",
"A > A2 > A2-1",
"B > B1"
}
var categoryList = new List<Category>();
for(int i=0; i < demoArray.Length; i++)
{
string[] categoryStringSplit = demoArray[i].Split('>');
RecurseProductCategories(categoryStringSplit, categoryList);
}