在 vb.net 中解析 xml
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19126720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
parse xml in vb.net
提问by CRAIGRY
I am given an XML file. It is formed like this:
我得到了一个 XML 文件。它的形成是这样的:
<?xml version="1.0" encoding="utf-8"?>
<dataset xmlns="http://developer.cognos.com/schemas/xmldata/1/" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
<!--
<dataset
xmlns="http://developer.cognos.com/schemas/xmldata/1/"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="http://developer.cognos.com/schemas/xmldata/1/ xmldata.xsd">
-->
<metadata>
<item name="Level" type="xs:short" precision="1"/>
<item name="ID" type="xs:string" length="14"/>
<item name="Name" type="xs:string" length="52"/>
</metadata>
<data>
<row>
<value>2</value>
<value>101 </value>
<value>Location 1</value>
</row>
<row>
<value>2</value>
<value>103 </value>
<value>Location 2</value>
</row>
</data>
I am having trouble parsing this. There are hundreds of articles online - but all of them have a different format than the data handed to me. Can anyone point me in the right direction for VB.NET on Framework 3.5? I am used to seeing data more like this:
我在解析这个时遇到问题。网上有数百篇文章——但所有文章的格式都与交给我的数据不同。任何人都可以为 VB.NET 在 Framework 3.5 上指出正确的方向吗?我已经习惯看到更像这样的数据:
<item name="Future" collected="yes">
EDIT: So, I have tried this:
编辑:所以,我试过这个:
Dim reader As XmlTextReader = New XmlTextReader(fileToSave)
Do While (reader.Read())
Select Case reader.NodeType
Case XmlNodeType.Element 'Display beginning of element.
Console.Write("<" + reader.Name)
Console.WriteLine(">")
Case XmlNodeType.Text 'Display the text in each element.
Console.WriteLine(reader.Value)
Case XmlNodeType.EndElement 'Display end of element.
Console.Write("</" + reader.Name)
Console.WriteLine(">")
End Select
Loop
What I need is the Row items to be able to populate a combobox - this just gives me the same thing as the XML file:
我需要的是能够填充组合框的 Row 项目 - 这只是给了我与 XML 文件相同的东西:
<dataset>
<metadata>
<item>
<item>
<item>
</metadata>
<data>
<row>
<value>
2
</value>
<value>
101
</value>
<value>
Location 1
</value>
</row>
<row>
<value>
2
</value>
<value>
103
</value>
<value>
Location 2
</value>
</row>
</data>
</dataset>
采纳答案by sloth
To extract data from XML in VB.Net, you could simply use VB.Net's XML literals (if you don't want to bother with XML transformation).
要在 VB.Net 中从 XML 中提取数据,您可以简单地使用 VB.Net 的 XML 文字(如果您不想打扰XML 转换)。
Given your xml:
鉴于您的 xml:
Dim xml As XDocument =
<?xml version="1.0" encoding="utf-8"?>
<dataset xmlns="http://developer.cognos.com/schemas/xmldata/1/" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
<metadata>
<item name="Level" type="xs:short" precision="1"/>
<item name="ID" type="xs:string" length="14"/>
<item name="Name" type="xs:string" length="52"/>
</metadata>
<data>
<row>
<value>2</value>
<value>101 </value>
<value>Location 1</value>
</row>
<row>
<value>2</value>
<value>103 </value>
<value>Location 2</value>
</row>
</data>
</dataset>
you can import its namespace with
你可以导入它的命名空间
Imports <xmlns="http://developer.cognos.com/schemas/xmldata/1/">
and then simply query your data like in the following examples:
然后像下面的例子一样简单地查询你的数据:
For Each element In xml...<value>
Console.WriteLine(element.Value)
Next
Console.WriteLine("----------")
For Each element In xml...<row>
For Each v in element.<value>
Console.WriteLine(v.Value)
Next
Next
Console.WriteLine("----------")
For Each element In xml...<row>
Dim s = element.<value>.Select(Function(e) e.Value.Trim())
Console.WriteLine(String.Join(" - ", s))
Next
Output:
输出:
2
101
Location 1
2
103
Location 2
----------
2
101
Location 1
2
103
Location 2
----------
2 - 101 - Location 1
2 - 103 - Location 2
回答by CRAIGRY
I believe the answer below should be to your liking. Most of my comments/editorials should explain the whole process. Turns out you're not the only person on stackoverflow having cognos dataset woes, lol. The example below was tested in LinqPad and returned desirable results.
我相信下面的答案应该是你喜欢的。我的大部分评论/社论都应该解释整个过程。事实证明,你并不是 stackoverflow 上唯一一个遇到 cognos 数据集问题的人,哈哈。下面的示例在 LinqPad 中进行了测试并返回了理想的结果。
Imports System.Data.Common
Imports System.Runtime.Serialization
Imports System.Xml.Xsl
Public Class Test
'Note: If you don't put the <?xml...?> doctype the XML literals VB.NET gives you will not create an XDocument, but an XElement
' This the sample XML document from your question
Private _xml As XDocument = <?xml version="1.0" encoding="utf-8"?>
<dataset xmlns="http://developer.cognos.com/schemas/xmldata/1/" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
<!--
<dataset
xmlns="http://developer.cognos.com/schemas/xmldata/1/"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="http://developer.cognos.com/schemas/xmldata/1/ xmldata.xsd">
-->
<metadata>
<item name="Level" type="xs:short" precision="1"/>
<item name="ID" type="xs:string" length="14"/>
<item name="Name" type="xs:string" length="52"/>
</metadata>
<data>
<row>
<value>2</value>
<value>101 </value>
<value>Location 1</value>
</row>
<row>
<value>2</value>
<value>103 </value>
<value>Location 2</value>
</row>
</data>
</dataset>
' This is a transform I found http://stackoverflow.com/questions/9465674/converting-a-cognos-xml-schema-file-to-xml-using-javascript-code, you're not the only one having trouble with this
Private _xmlTransform As XDocument = <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns="http://tempuri.org/" xmlns:cog="http://developer.cognos.com/schemas/xmldata/1/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="//comment()" />
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="cog:dataset">
<rows>
<xsl:apply-templates />
</rows>
</xsl:template>
<xsl:template match="cog:metadata">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="cog:item">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="@name | @type | @length | @precision" />
<xsl:template match="cog:data">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="cog:row">
<row>
<xsl:apply-templates />
</row>
</xsl:template>
<xsl:template match="cog:value">
<xsl:variable name="currentposition" select="count(./preceding-sibling::cog:value)+1" />
<xsl:variable name="currentname" select="//cog:metadata/cog:item[$currentposition]/@name" />
<xsl:element name="{$currentname}">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
' This is the XSLT .NET object that will allow us to translate your dataset into something usable
private _tranform As XslCompiledTransform = new XslCompiledTransform()
' Meat & Potatoes, where the dataset will be set to
public Property MainDataSet As DataSet
Sub Main
' using XDocument, we can create a reader and then prepare the tranform...
_tranform.Load(_xmlTransform.CreateReader(), new XsltSettings(true,true), Nothing)
' I am using "Using" here because, but you're more than welcome to use .Dispose, I'm a C# dev at heart, I'm just forced to code VB.NET for my day job
Using _ds = new DataSet()
' The XmlTextWrite constructor allows a StringBuilder; which will keep everything in-memory, per your comments
Dim _sb As StringBuilder = new StringBuilder()
' Create an XmlTextWriter with the StringBuilder as the output-buffer
Using _xmlWriter = XmlTextWriter.Create(_sb)
' Commit tranformation of the original dataset xml
_tranform.Transform(_xml.CreateReader(), _xmlWriter)
' Have the interim DataSet read-in the new xml
_ds.ReadXml(new StringReader(_sb.ToString()), XmlReadMode.Auto)
' ... keeping it clean here... lol
_xmlWriter.Close()
' Set the class property to the rendered dataset.
MainDataSet = _ds
End Using
End Using
End Sub
End Class
回答by Joe
You can use the System.IO.File.WriteAllLinesor System.IO.File.WriteAllTextmethod, and set the extension as XML
您可以使用System.IO.File.WriteAllLinesorSystem.IO.File.WriteAllText方法,并将扩展名设置为 XML

