我为发布这个而道歉,因为它可能是一个非常简单的过程,但在尝试了一些方法后,我仍然无法理解这项工作的最佳方法。
我创建了一个带有硬编码设置的程序,但是我想让它稍后解析XML文件和数据作为设置,以便其他用户可以更新程序而无需更新整个程序(目前只有我自己才能做到这一点,用户友好的XML文件才能创造奇迹。)
到目前为止,我正在测试另一个项目中的XML读取和处理,以便在将任何代码导入到我的主程序之前了解它,但我查看了XMLReader和System.Xml.XmlDocument并且没有知道哪些对我想要实现的目标最有效。
我正在使用的XML是:
<ProgramName
updated="11/12/13"
lastuser="james.xxxxxxx"
>
<school name="school name" id="1">
<netbios> NETBIOS </netbios>
<domainname> SCHOOLNAME.local </domainname>
<drives>
<!-- Generic variables -->
<variable name="server1"> \\server1\ </variable>
<variable name="server2"> \\server2\ </variable>
<!-- Work drives -->
<!-- Note, you can use $server1 or $server2 to use the above variables -->
<restriction usergroup="office users">
<drive name="Home Drive"> \\server1\officework$ </drive>
<drive name="Office Drive"> \\server1\Office Shared </drive>
</restriction>
<restriction usergroup="staff users">
<drive name="Home Drive"> \\server1\staffwork$ </drive>
</restriction>
<restriction usergroup="all users">
<drive name="Staff Shared"> \\server1\staff shared </drive>
<drive name="Pupil Shared"> \\server1\pupil shared </drive>
<drive name="Another drive"> \\server1\another drive </drive>
</restriction>
</drives>
</school>
</ProgramName>
我试图让XML看起来像我想的那样“漂亮”和合乎逻辑,以便我的同事可以在没有任何进一步知识的情况下更新它(他们是IT工程师,但不了解编程知识)。
基本上,我很感激您就我的程序中保存这些数据的最佳方法提出建议。我是否运行XML文件并将部分保存到多维/多个列表,Arraylists等? 请注意,对于不同的学校,将重复多次,因此文件可能会相对较大。
我的程序将做的一件事是根据用户所属的用户组映射驱动器并相应地命名(例如,来自'name'属性),因此它必须遍历所有相应的驱动器,所以(对我来说)将事物保存到某种列表/数组/集合然后运行它是有意义的。
我已经读过使用System.Xml.XmlDocument比XMLReader更灵活,但是我遇到了重复条目,性能不佳,没有终端元素检测的问题。也许我的很多问题源于对其背后的过程或逻辑的理解。
我还想扩展其用途来做其他事情,但我已经陷入了阅读XML文件的第一个障碍。如果有任何帮助的话,我可以发布我的混合代码,但我认为一个全新的视角可能比调整那些远远不能达到良好水平的代码更有用。
真诚的道歉,如果这对SO来说是不合适的,或者我发布了这个错误。
亲切的问候, 詹姆斯。
编辑:有没有办法可以在不回答自己的情况下完整回复?
我附上了用于测试的代码(这只是为了可视化它的工作原理)。
Public Sub DisplayNodes(_XMLNodes As Xml.XmlNodeList)
For Each xNode As System.Xml.XmlNode In _XMLNodes
Select Case xNode.NodeType
Case XmlNodeType.Element
Output("Element: " & xNode.Name)
If xNode.Attributes.Count > 0 Then
For Each attribute As System.Xml.XmlAttribute In xNode.Attributes
Output("Attribute: " & attribute.Name & " = " & attribute.Value)
Next
End If
End Select
If xNode.HasChildNodes Then
DisplayNodes(xNode.ChildNodes)
End If
Next
End Sub
然后我的想法是把它转换成可以直接引用的东西,我想这将是一个新的对象(我仍然在为什么是为某事创建一个新对象的最佳时间)。
我想我会使用XPath来找到合适的部分(例如,用户选择的学校),然后我需要考虑驱动器地图的最佳存储类型,以便我可以遍历它们。
在硬编码版本中,我使用了一个Collection,其中Key是驱动器号,值是UNC路径,并循环通过集合来映射它们。不知道,我知道。
感谢。
修改2
我刚刚发现http://support.microsoft.com/kb/301220并且使用XPath看起来很有希望。
我会找到用户选择的学校,然后从这里我将创建一个包含所有相关元素(netbios,域名等)的对象,你会建议使用某种列表/数组来驱动?
对此感到乐观,我会告诉你的! 感谢。
答案 0 :(得分:0)
关于您的一般问题:
根据数据的用法,我想我会创建一个或多个与数据相对应的类。这就像血清/消毒,但你可能不得不做这样的自定义实现。
我不明白的是您对使用System.Xml.XmlDocument的“无结束元素检测”问题的评论。这意味着加载的Xml没有很好地形成,这使我认为你是通过字符串操作创建xml。
您至少应该能够执行以下操作:
Dim doc as XmlDocument = new XmlDocument()
doc.LoadXml(fullFileNamePath)
如果你不能,那么你需要在进一步推进之前使你的xml成型。
许多事情都可能导致性能不佳。你的文件有多大? 应用:我认为你需要解释(一个小的具体例子)。 通常你可以做类似的事情:
doc.SelectNodes("/ProgramName/school/drives/restriction[@usergroup = 'office users']/drive"/>
选择名为“Home Drive”和“Office Drive”的两个驱动器元素。 这需要有关xpath的知识。
另一种方法是使用XElement和LINQ,但我对此没有多少经验。