2013-10-01 95 views
1

我給了一個XML文件。它是這樣形成:解析xml在vb.net

 <?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> 

我無法解析此。網上有數百篇文章 - 但所有文章的格式都不同於交給我的數據。 任何人都可以指出我在正確的方向爲VB.NET在Framework 3.5? 我習慣看到的數據更是這樣的:

<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 

我需要的是行項目能夠填充ComboBox - 這只是給了我同樣的事情,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> 
+0

查看[XDocument](http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.aspx)。 – Magnus

+0

你想從XML中查詢什麼?向我們展示您遇到問題的代碼。 –

+0

這就是艾哈邁德,我不知道從哪裏開始。我需要標籤中的值。 – CRAIGRY

回答

1

要在VB.Net提取XML數據,你可以簡單地使用VB.Net的XML文本(如果你不想XML transformation打擾)。

鑑於你的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 
+0

我必須做「爲每個元素作爲xml元素... 」,它的工作原理非常棒!感謝你這個易於使用的代碼。順便說一句,什麼是「xml ... 」 - 我對XML很新。 – CRAIGRY

+0

最後一個不起作用:在WLC.exe中發生類型'System.InvalidCastException'的第一次機會異常 System.InvalidCastException:無法強制類型爲'WhereSelectEnumerableIterator'2 [System.Xml.Linq.XElement,System。字符串]'鍵入'System.String []' – CRAIGRY

-1

可以使用System.IO.File.WriteAllLinesSystem.IO.File.WriteAllText方法,並設定擴展s XML

+0

喬,如果我想寫一個XML文件,我會的。但需要解析該文件並獲取數據。 – CRAIGRY

1

我相信下面的答案應該是你喜歡的。我的大多數評論/社論都應該解釋整個過程。原來你並不是唯一一個擁有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 
+0

似乎,stackoverflow仍然沒有掌握在vb.net的xml文字,如果你想更好的代碼着色我有代碼克隆[這裏](https://gist.github.com/Steinerd/bee0b45475ffcd09e032) – 2013-10-02 04:07:16

+0

另外一種XSL轉換也適用於'DataSet',可以在這裏找到:[IBM Cognos BI:表格數據的通用XSLT標準化](http://code.dblock.org/ibm-cognos-bi-generic-xslt-normalization -for-table-data) – sloth

+0

我的回答有幫助嗎?這對我來說都是新的,我很欣賞學習新事物,只是想知道我的執行是否在範圍之內。大聲笑 – 2013-10-02 11:30:35