在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 15:18:40  来源:igfitidea点击:

parse xml in vb.net

xmlvb.netlinq

提问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