2014-04-17 35 views
0

我有一个显示树结构的文本文件。空格数表示给定成员的级别。例如下面,用户组的成员或亚组谁可以拥有成员等儿子:从.NET中的文本文件构建XML树

MainGroup 
Member1 
Member2 
Group1 
    Member11 
    Member12 
    Group12 
    Member21 
    Member22 
Member3 

对不起大家,我 第一次和第一个问题在这里所以是搞清楚整个事情的格式。

这是我到目前为止已经试过:(这是没有必要的,但我需要的数据表,以显示我的数据)

  1. 我读的文本文件导入数据表。
  2. 通过每行(有一列),我创建一个节点。我找到了空格的数量。如果它为零,我将属性添加到此节点并将其添加到doc。如果它有空格,我循环并继续向此节点添加子节点。这是事情不适合我的地方。

    Sub ExportToEXML 
        Dim datarow As DataRow 
        Dim fileName As String = "" 
        Dim level As Integer = 0 
        Dim counter As Integer = 0 
        Dim doc As XmlDocument = New XmlDocument 
        Dim docNode As XmlNode = doc.CreateXmlDeclaration("1.0", "UTF-8", Nothing) 
        doc.AppendChild(docNode) 
        Dim ComponentsNode As XmlNode = doc.CreateElement("Components") 
        doc.AppendChild(ComponentsNode) 
    
        Dim firstrow As DataRow 
    
        For i As Integer = 0 To dt.Rows.Count - 1 
         firstrow = dt.Rows.Item(i) 
         fileName = firstrow(0) 
         level = CountSpacesBeforeFirstChar(fileName) 
    
         Dim partNode As XmlNode = doc.CreateElement("Component") 
         Dim att As XmlAttribute = doc.CreateAttribute("Name") 
         att.Value = fileName 
         partNode.Attributes.Append(att) 
         GetChildNodes(partNode, i, doc, 0, level, dt) 
         ComponentsNode.AppendChild(partNode)     
        Next 
        doc.Save("D:\TestXML.xml")  
    End Sub 
    
    Private Sub GetChildNodes(ByRef xNode As XmlNode, ByRef rowInd As Integer, ByRef xDoc As XmlDocument, level As Integer, table As DataTable) 
    
        Dim lev As Integer 
        Dim fileName As String 
        Dim dr As DataRow 
        For i As Integer = rowInd + 1 To table.Rows.Count - 1 
         dr = table.Rows.Item(i) 
         fileName = dr(0) 
         lev = CountSpacesBeforeFirstChar(fileName) 
         If lev = 0 Then 'has no children 
          Exit Sub 
         End If  
    
         If lev > level Then 
          Dim partNode As XmlNode = xDoc.CreateElement("Component") 
          Dim att As XmlAttribute = xDoc.CreateAttribute("Name") 
          att.Value = fileName 
          partNode.Attributes.Append(att) 
          xNode.AppendChild(partNode) 
          GetChildNodes(xNode, i, xDoc, lev, table) 
    
         End If 
        Next   
    End Sub 
    
+1

您尝试了什么?你在哪里遇到问题?发布您的代码。 – qqbenq

+0

你能解释一下“空格数表示给定成员的级别”是什么意思吗?它是一个固定宽度的文本文件吗? – wooters

回答

1

那么,你应该阅读该文件(如果它不是太大读取整个入内存,否则不会),创建一个空的XML文档,通过线迭代,并且根据的压痕行创建新节点并将它们添加到适当的XML元素(例如跟踪每个级别的“最后”节点并将它们添加为子元素)。当然,您可以将XML创建延迟到以后的阶段,并根据文件内容构建对象层次结构,并在完成后简单地序列化它。或者,也许这整个事情可以用一个聪明的正则表达式来完成。有很多可能的解决方案。

但坦率地说:SO不是你不费力就能神奇地获得代码的地方。 (当然,有时,但尽管如此:告诉我们你做一些努力,你问一个非常普遍的问题之前,其实解决这个问题。)

0

这里是做这个相对简洁的方式:

Sub ParseHierarchy(ByRef inputFilePath As String, ByRef outputFilePath As String) 
    ' We'll treat depth as zero-based to match the number of spaces in the lines 
    Dim depth As Integer = -1 
    Dim settings As XmlWriterSettings = New XmlWriterSettings 
    settings.Indent = True 

    Using writer As XmlWriter = XmlWriter.Create("testxml.xml", settings) 
     For Each line As String In File.ReadLines(inputFilePath) 
      Dim nextDepth As Integer = GetLineDepth(line) 

      If nextDepth - depth > 1 Then 
       Throw New ApplicationException(_ 
        "Depth cannot increase by more than 1 at a time.") 
      End If 

      '' Close any elements at a deeper or the same depth as the next one 
      CloseElements(writer, depth - nextDepth + 1) 
      depth = nextDepth 

      writer.WriteStartElement("Component") 
      writer.WriteAttributeString("Name", line.Trim()) 
     Next 

     '' Close any elements that are still open 
     CloseElements(writer, depth + 1) 
    End Using 
End Sub 

Private Sub CloseElements(ByRef writer As XmlWriter, ByVal count As Integer) 
    For i = 1 To count 
     writer.WriteEndElement() 
    Next 
End Sub 

Private Function GetLineDepth(line As String) As Integer 
    Return Regex.Match(line, "^\s*").Length 
End Function 

在您的示例文件上运行时,输出为:

<Component Name="MainGroup"> 
    <Component Name="Member1" /> 
    <Component Name="Member2" /> 
    <Component Name="Group1"> 
    <Component Name="Member11" /> 
    <Component Name="Member12" /> 
    <Component Name="Group12"> 
     <Component Name="Member21" /> 
     <Component Name="Member22" /> 
    </Component> 
    </Component> 
    <Component Name="Member3" /> 
</Component> 
+0

这正是我想要做的。谢谢! – user3546141