簡體   English   中英

在vb.net中解析xml

[英]parse xml in vb.net

我得到一個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>

我在解析此文件時遇到了麻煩。 在線上有數百篇文章-但是所有文章的格式都不同於提交給我的數據。 誰能為我指出Framework 3.5上VB.NET的正確方向? 我習慣於看到更多這樣的數據:

    <item name="Future" collected="yes">

編輯:所以,我試過了:

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

我需要的是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>

我相信下面的答案應該是您的喜好。 我的大部分評論/社論都應解釋整個過程。 事實證明,您不是唯一有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

要從VB.Net中的XML提取數據,您可以簡單地使用VB.Net的XML文字(如果您不想打擾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>

您可以使用導入其名稱空間

Imports <xmlns="http://developer.cognos.com/schemas/xmldata/1/">

然后像下面的示例一樣簡單地查詢您的數據:

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    

輸出:

2
101   
Location 1
2
103   
Location 2
----------
2
101   
Location 1
2
103   
Location 2
----------
2 - 101 - Location 1
2 - 103 - Location 2

您可以使用System.IO.File.WriteAllLinesSystem.IO.File.WriteAllText方法,並將擴展名設置為XML

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM