2017-05-05 4 views
0

本当に初心者の質問にお詫び申し上げます。私は、VBでXMLを使用することに非常に慣れており、批判的な理解に達するためにいくつかのガイダンスが必要です。XElementと.Elementを使用したXMLのクエリ

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <Candy ID="MnMs"> 
    <Form ID="tablet" Name="Tablet"> 
     <Component ID="shell" Ingredients="sugar"/> 
     <Component ID="filling" Ingredients="chocolate"/> 
    </Form> 
    <Form ID="oblong"> 
     <Component ID="shell" Ingredients="sugar"/> 
     <Component ID="filling" Ingredients="chocolate"/> 
     <Component ID="center" Ingredients="nut"/> 
    </Form> 
    </Candy> 
    <Candy ID="LBalls"> 
    <Form ID="sphere"> 
     <Component ID="shell" Ingredients="chocolate"/> 
     <Component ID="filling" Ingredients="chocolate ganache"/> 
    </Form> 
    </Candy> 
    <Candy ID="RPieces"> 
    <Form ID="tablet"> 
     <Component ID="shell" Ingredients="sugar"/> 
     <Component ID="filling" Ingredients="peanut butter ganache"/> 
    </Form> 
    </Candy> 
</xs:schema> 

IDの使用ではなく、推奨(より典型的に注意してください)id?。)

VBで、私がアクセスする方法を、:様々なキャンディーを説明し、次のXMLを考える

Ingredientsの属性<Component> RPieces/tablet/filling?具体的には、次の行:

<Component ID="filling" Ingredients="peanut butter ganache"/> 

私のVB関数は次のとおりです。アイデンティティがどのように管理されているのか、特に属性がIDidであることを考えると、私は混乱しています。

Imports System.IO 
Imports System.Xml 
... 
Function CandyFetch(ByVal candyId As String, ByVal formId As String, ByVal compId As String, ByVal attrId As String, Optional ByVal docPath As String = "Candies.xml") As String 
    Const ID = "ID" 
    Dim result = "" 
    docPath = docPath.Trim() 
    If Not File.Exists(docPath) Then docPath = AppDomain.CurrentDomain.BaseDirectory + docPath 
    For Each bonbon In XElement.Load(docPath).Elements("Candy") 
     If bonbon.Attribute(ID).Value = candyId Then 
      For Each form In bonbon.Elements("Form") 
       If form.Attribute(ID).Value = formId Then 
        For Each component In form.Elements("Component") 
         If component.Attribute(ID).Value = compId Then 
          result = component.Attribute(attrId).Value 
          Exit For 
         End If 
        Next 
       End If 
      Next 
     End If 
    Next 
    Return result 
End Function 

ありがとうございます。

ここでは、LinqToXmlを使ってこれを行う簡単な方法がありますが、XML要素を反復処理する必要はありませんか?

答えて

0

私は、XPathクエリを使用することをお勧めします:

Dim filename As String = "C:\Junk\example.xml" 
Dim xdc As New XmlDocument 
xdc.Load(filename) 
Dim nsm As New XmlNamespaceManager(xdc.NameTable) 
nsm.AddNamespace("xs", "http://www.w3.org/2001/XMLSchema") 
Dim strXPATH As String = "/xs:schema/Candy[@ID=""RPieces""]/Form/Component[@ID=""filling""]/@Ingredients" 
MsgBox(strXPATH & "=" & vbCrLf & 
     xdc.DocumentElement.SelectSingleNode(strXPATH, nsm).InnerText) 
+0

begi以下のようになります。 nner、here ... just Dim strXML =外部ファイルからテキストを読み込むFile.ReadAllText(docPath)? ...またはXDocument.Loadなどを使用する必要がありますか? – user1601638

+0

'XmlDocument.Load'を使って、メモリ内の' String'を解析するのではなく、ファイルを読み込むことができます。私は私の答えを更新しました – SSS

0

LINQで、それはあなたが少しのコードを作成できるXML軸のプロパティを持つXMLにLINQを使用することにより

以下
Dim doc As XDocument = XDocument.Load(docPath) 
Dim value = doc.Descendants("Candy"). 
       Where(Function(candy) candy.Attribute("ID").Value = "RPieces"). 
       SelectMany(Function(candy) candy.Elements("Form")). 
       Where(Function(form) form.Attribute("ID").Value = "tablet"). 
       SelectMany(Function(form) form.Elements("Component")). 
       Where(Function(component) component.Attribute("ID").Value = "filling"). 
       Select(Function(component) component.Attribute("Ingredients").Value). 
       FirstOrDefault() 

のように見えることができますXMLに入札は簡単です。
XML Attribute Axis Property (Visual Basic)

Dim doc As XDocument = XDocument.Load(docPath) 
Dim value = doc...<Candy>. 
       Where(Function(candy) [email protected]<ID> = "RPieces"). 
       <Form>. 
       Where(Function(form) [email protected]<ID> = "tablet"). 
       <Component>. 
       Where(Function(component) [email protected]<ID> = "filling"). 
       Select(Function(component) [email protected]<Ingredients>). 
       FirstOrDefault() 

あなたがコードに名前空間をインポートする場合は、別のアプローチ軸プロパティの

をelments/attirbutesの名前を書くためのインテリセンスの助けを得るでしょうシリアライズを使用している、あなたの構造を表したクラスを作成しますXMLは、その後、あなたのコードはまだ

Dim serializer As New XmlSerializer(GetType(YourRootClass)) 
Dim data As YourRootClass = Nothing 
Using fileStream As New FileStream(docPath, FileMode.Open) 
    data = serializer.Deserialize(fileStream) 
End Using 

Dim value = data.Candies. 
       Where(Function(candy) candy.ID = "RPieces"). 
       SelectMany(Function(candy) candy.Forms). 
       Where(Function(form) form.ID = "tablet"). 
       SelectMany(Function(form) form.Components). 
       Where(Function(component) component.ID = "filling"). 
       Select(Function(component) component.Ingredients). 
       FirstOrDefault() 
関連する問題