2013-10-01 75 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