ארכיון תגיות: MSXML

תקלת XML – שנקראת Invalid at the top level of the document

אני משתמש ב-MSXML כדי לקבל XML באמצעות VBA, שנשלח מ-PHP .

מסיבה לא ברורה, לפעמים יש סימן שאלה *לפני* התו הראשון.
זה נראה כך :

?

מה שגורם לתקלה "קטנה" ב-XML.

הבעיה : תקלות ב-MSXML לא תמיד מדווחות כתקלות VBA
לכן קשה לדעת שהייתה תקלה כי (Err.number=0)

פתרונות משולבים :
1. כדי לדעת אם הייתה תקלה יש להשתמש ב
xmlOBJECT.parseError.errorCode - עבור הקוד של התקלה
ועבור התיאור ב - reason במקום errorcode.

2. כדי להתמודד עם זה, יש לזהות את הקוד ASCII של התו הראשון, ולנקות אותו.

בניה/יצירה של XML פשוט ב-MSXML (VBA)

ככה יוצרים אוביקט XML פשוט ב-MSXML
הדוגמא היא ב-VBA

הדוגמא יוצרת
1. מסמך
2. root node – כלומר הענף המרכזי של העץ
3. ענף "בן" אחד
4. מאפיין/attritube עבור ה-root node

בסוף היא מחזירה את ה-XML, אבל אם רוצים לשמור צריך להשתמש במתודה SAVE.


  Dim mydata As Object, pi As Object
  Dim Node As Object, Child As Object, att As Object
   'create an object, Late Binding
   Set mydata = CreateObject("Msxml2.DOMDocument.6.0")
   'create the first line, before the root element
   Set pi = mydata.createProcessingInstruction("xml", "version='1.0' encoding='UTF-8'")
   'now writes the the first line to the XML object
   mydata.InsertBefore pi, mydata.FirstChild
   
   'create root node
   Set Node = mydata.createElement("smart")
   'set attribute to the root node
    Node.setAttribute "goal", "login"
    'create child node
    Set Child = mydata.createElement("time")
    'set a text value to the child node
    Child.Text = Now
    'put the child under the first=root Node
    Node.appendchild Child
    'put the root node under the documnet object
   mydata.appendchild Node
   'return all the xml as string
   XMLobj = mydata.XML
End Function

איך לשלוח מידע ב-POST דרך msxml ( Late Binding

הדוגמא הבאה מראה שליחת מידע ב-POST דרך אוביקט xmsml
הדוגמא על VBA

יש לקחת בחשבון שצריך כמובן גם לפתח את הדף שמקבל את הנתונים שיחזיר תשובה כלשהיא – כדי לבדוק את הנתונים.

נקודה חשובה : במשלוח בפוסט, מחברים את הערכים באמצעות סימן &
כלומר

yourVariable=yourValue&anotherVariable=anotherValue

וזה הקוד VBA

Function PostXmlData(vUrl As String, xmlText As String)
Dim XMLHttp As Object
Set XMLHttp = CreateObject("MSXML2.XMLHTTP")

XMLHttp.Open "POST", vUrl, False
XMLHttp.setRequestHeader "Content-type", "application/x-www-form-urlencoded" 'charset=utf-8

XMLHttp.send (xmlText)

PostXmlData = XMLHttp.responseText
Debug.Print PostXmlData
End Function

התמודדות עם EntityRef: expecting ';' in Entity (מחרוזת XML שעוברת מ-MSXML אל PHP XML DOM )

יש לי מודול באחד התוכנות
שמשדר XML מתוך אקסל באמצעות MSXML גירסה 2 של MICROSOFT

אל Web Service ב-PHP

והשירות מחזיר XML בחזרה, כאשר ה-XML נשמר כרשומות בדאטאבייס.

עכשיו – מסתבר שלמרות שיש תקן מאוד ברור ל-XML

אז MSXML – לפעמים מתעלם ממנו.

היתה לי שורה שהכילה את מדד המניות האמריקאי – S&P

כמו שאתם רואים בין האותיות יש את סימן ה- &

אז ה-MSXML מכניס אותו למחרוזת בלי בעיה, למרות שזה לא תקין,

כי לפי ההגדרות – זהו סימן שמור שאמור להפוך לamp

זאת ההגדרה :

'&' (ampersand) becomes '&'

טוב… מה שקרה הוא כמובן תקלה, כי המרכיב ב-PHP שמקבל את זה , XML DOM (אוביקט DOMDocument )

לא ידע לאכול את זה….

הפתרון הוא ממש פשוט במקרה זה ,

רגע לפני שטוענים את ה-מחרוזת XML אל תוך האוביקט

צריך להפוך את הסימני & למשהו אחר.

ככה זה ב-php :

$tmp = str_replace('&','-',$tmp);

בהצלחה!

שמירת רשימת ערכים ממערך בתוך XML (פונקצית VBA )

הרבה פעמים אנחנו צריכים לשמור רשימה משתנה של ערכים.

בצורה של
מפתח = ערך
(key = value )

להלן פונקציה פשוטה שכתבתי שלוקחת מערך דו מימדי
כאשר בכל שורה יש 2 איברים
איבר מספר 1 – שם המאפיין
איבר מספר 2 – ערך המאפיין

הפונקציה מחזירה XML שמכיל את כל הערכים במערך

Public Function ArrayToXML(yAry As Variant) As String
    'This Function Get a 2 dimenesions array, and return XML string
    'On each row of the array need to be with 2 columns :
    '     1 - the name
    '     2 - the value
  Dim XmlObj As Object, pi As Object, I As Integer
  Dim Node As Object, Child As Object, att As Object
   'create an object, Late Binding
   Set XmlObj = CreateObject("Msxml2.DOMDocument.6.0")
   'create the first line, before the root element
   Set pi = XmlObj.createProcessingInstruction("xml", "version='1.0' encoding='UTF-8'")
   'now writes the the first line to the XML object
   XmlObj.InsertBefore pi, XmlObj.FirstChild
   'create root node
   Set Node = XmlObj.createelement("YourXmlRootNodeName")
        'Loop on the array
        For I = LBound(yAry, 1) To UBound(yAry, 1)
            'Create a Child node
             Set Child = XmlObj.createelement(yAry(I, 1))
            'Put the value
             Child.Text = yAry(I, 2)
            'put this Child node under the root node
            Node.appendchild Child
        Next I
    
    
    'put the root node under the documnet object
   XmlObj.appendchild Node
   'return all the xml as string
   ArrayToXML = XmlObj.xml
   
End Function

לולאה על ענפים של XML בפונקצית VBA

הפונקציה הבאה יכולה לשמש בסיס להרבה דברים

אם יש לך XML,

ואתה יודע לכתוב את שאילתת ה-XPATH הרצויה

אז בפונקצית VBA הבאה אתה מקבל את כל הענפים של השאילתא ששלחת.

כמובן שאת השורה באמצע הלולאה (שורת ה-Debug.Print ) תחליפו במה שנחוץ אצלכם


    Dim XmlObj As Object, XmlRoot As Object, XPathQuery As String, SingleNode As Object
    
     'îðúç àú äúùåáä
     Set XmlObj = CreateObject("Msxml2.DOMDocument.6.0")
     XmlObj.LoadXML XmlStr
     Set XmlRoot = XmlObj.DocumentElement
     
     XPathQuery = "//smart/*"
     Set xmlNodeList = XmlObj.SelectNodes(XPathQuery)
            
    For Each Node In xmlNodeList
        Debug.Print Node.nodename & " = " & Node.Text
     Next