2016-12-04 32 views
1

我試圖獲得對XML數據的匹配字符串作爲一個特定ID,並從列表框中的名稱VB.NET正則表達式匹配。對XML數據

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click 
    'website 
    Dim link As String = "https://s25-pt.ogame.gameforge.com/api/players.xml" 

    Dim html As String 
    'name selected on listbox 
    Dim jogador As String = ListBox1.Text 
    Dim pattern As String = "player id=""(.*?)"" name=""" & jogador & """" 


    webc1 = New WebClient 
    webc1.Headers.Add("user-agent", "Mozilla/5.0 (Windows; U; Windows NT 5.0; es-ES; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3") 

    html = webc1.DownloadString(link) 


    Dim match As Match = Regex.Match(html, pattern) 

    If match.Success Then 
     MsgBox(match.Groups(1).Value) 
    End If 
End Sub 

我沒有得到只是id,但我也得到了一個'html'字符串的大片。

我試圖尋找答案的谷歌,我試過其他方式,但我不明白如何來解決這個問題。有沒有一種方法可以改進我的正則表達式?

我知道這是一個XML,我可能會使用其他方法更合適得到它,但我覺得這是比較容易的方式。

回答

1

如果你在regex101上試試你的正則表達式,那麼它可以正常工作,以pcre/php模式運行。但是,.NET正則表達式與其他實現稍有不同。

所以,我這個正則表達式試圖代替,並得到了正確的比賽:

player id="(\d+)" name="sniper lord" 

。給我1000042從您的數據的結果。

\d+只是意味着一個或多個數字 - 您的XML數據表明玩家ID是數字只所以這個「收緊」的正則表達式。這也採用sniper lord作爲jogador的測試值。

或許你也可以使用String.Format命令,以幫助用雙引號的稍微有一些混亂運行:

Dim pattern As String = String.Format("player id=""{0}"" name=""{1}""", "(\d+)", jogador) 
+0

這很好用。感謝您的幫助和詳細的解釋。 :) –

1

我只是無法抗拒這一點,因爲正則表達式對XML僅僅是不是一個好主意。

您對樣品XML鏈接還跟提供了一個模式:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="players"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element name="player" maxOccurs="unbounded"> 
        <xs:complexType> 
         <xs:attribute name="id" use="required" type="xs:integer"/> 
         <xs:attribute name="name" use="required" type="xs:string"/> 
         <xs:attribute name="status" use="optional"> 
          <xs:simpleType> 
           <xs:restriction base="xs:string"> 
            <xs:pattern value="(a|[vIibo]+)"/> 
           </xs:restriction> 
          </xs:simpleType> 
         </xs:attribute> 
         <xs:attribute name="alliance" type="xs:string"/> 
        </xs:complexType> 
       </xs:element> 
      </xs:sequence> 
      <xs:attribute name="timestamp" type="xs:integer"/> 
      <xs:attribute name="serverId" type="xs:string"/> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

這將產生以下兩個類(我們不關心在這種情況下限制):

Imports System.Net 
Imports System.IO 
Imports System.Text 
Imports System.Collections.Specialized 
Imports System.Xml.Serialization 
Imports System.Diagnostics 
Imports System.Collections.Generic 
Imports System.Linq 

<XmlType(AnonymousType:=True, TypeName:="players"), XmlRoot(ElementName:="players")> 
Public Class PlayerList 
    <XmlElement("player", Form:=XmlSchemaForm.Unqualified, ElementName:="player")> 
    Public Property Players() As New List(Of Player) 

    <XmlAttribute(AttributeName:="timestamp"), DefaultValue(0)> 
    Public Property Timestamp() As Integer 

    <XmlAttribute(AttributeName:="serverId"), DefaultValue("")> 
    Public Property ServerId() As String 

    Public Function Find(PlayerName As String) As Player 
     Return Players.FirstOrDefault(Function(p) p.Name = PlayerName) 
    End Function 
End Class 

<XmlType(AnonymousType:=True, TypeName:="player"), XmlRoot("player")> 
Public Class Player 
    <XmlAttribute(AttributeName:="id"), DefaultValue(0)> 
    Public Property Id() As Integer 

    <XmlAttribute(AttributeName:="name"), DefaultValue("")> 
    Public Property Name() As String 

    <XmlAttribute(AttributeName:="status"), DefaultValue("")> 
    Public Property Status() As String 

    <XmlAttribute(AttributeName:="alliance"), DefaultValue("")> 
    Public Property Alliance() As String 
End Class 

我已經添加在PlayerList類Find功能,爲您的按鈕處理程序調用:

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click 
    Dim Link As String = "https://s25-pt.ogame.gameforge.com/api/players.xml" 
    Dim MyPlayers As PlayerList = Nothing 

    With New WebClient 
     .Headers.Add("user-agent", "Mozilla/5.0 (Windows; U; Windows NT 5.0; es-ES; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3") 
     MyPlayers = Deserialize(.DownloadString(Link), GetType(PlayerList)) 
     .Dispose() 
    End With 

    Dim MyPlayer As Player = MyPlayers.Find(ListBox1.Text) 
    If MyPlayer IsNot Nothing Then 
     Debug.Print("Player ID: {0}", MyPlayer.Id) 
     Debug.Print("Player Name: {0}", MyPlayer.Name) 
     Debug.Print("Player Status: {0}", MyPlayer.Status) 
     Debug.Print("Player Alliance: {0}", MyPlayer.Alliance) 
    Else 
     Debug.Print("Not Found") 
    End If 
End Sub 

Private Function Deserialize(XMLString As String, ObjectType As Type) As Object 
    Return New XmlSerializer(ObjectType).Deserialize(New MemoryStream(Encoding.UTF8.GetBytes(XMLString))) 
End Function 

使用Fantasma2進行測試我得到以下輸出:

Player ID: 100110 
Player Name: Fantasma2 
Player Status: vI 
Player Alliance: 4762 
+0

太不可思議了代碼!它看起來非常專業,它也會非常有用!我試圖使用XML來讀取數據,但我無法得到它的工作。謝謝:D –