Вот совершенно новая версия вашего кода, использующая «лучшие практики» (то есть не нужно экранировать символы вручную, не создавать XML из строк, но вместо этого использовать DOM, используя текущие объекты COM (Microsoft.XMLHTTP
устарела). 1002 *
Обратите внимание, что NewElem()
и GetText()
- это вспомогательные функции, которые находятся в конце кода.
NewElem()
создает новый элемент с пространством имен или без него и добавляет к нему текстовое значение
GetText()
ищет контекст (документ или узел) для выражения XPath и возвращает текстовое значение первого найденного элемента, или ""
(то есть умнее .selectSingleNode()
)
ASP код:
Option Explicit
Const NODE_ELEMENT = 1
Dim Namespaces, XmlHttpReq, InputDoc, OutputDoc, Channel, x, NewItem
Dim url, StubFeed, v, vGender, vAgeGroup, vColor, vSize
url = "http://thesite.com/v/myxml.xml"
StubFeed = "<rss version='2.0' xmlns:g='http://base.google.com/ns/1.0'><channel><title>store</title><link>http://www.thesite.com</link><description>This is a sample feed</description></channel></rss>"
' prepare a dictitionary of namespace prefixes and respective URIs
Set Namespaces = Server.CreateObject("Scripting.Dictionary")
Namespaces.Add "g", "http://base.google.com/ns/1.0"
Set OutputDoc = Server.CreateObject("MSXML2.DOMDocument.4.0")
Set XmlHttpReq = Server.CreateObject("MSXML2.XMLHTTP.4.0")
' retrieve the source document
' TODO: Error handling in case the HTTP request fails!
XmlHttpReq.Open "GET", url, False
XmlHttpReq.Send
Set InputDoc = XmlHttpReq.responseXML
' the stub of the output is loaded from string
OutputDoc.loadXML StubFeed
' all new items are appended to this element
Set Channel = OutputDoc.selectSingleNode("/rss/channel")
For Each x In InputDoc.selectNodes("//SAVED_EXPORT")
Set NewItem = OutputDoc.createElement("item")
With NewItem
.appendChild NewElem("g:id", GetText(x, "id"))
.appendChild NewElem("title", GetText(x, "title"))
.appendChild NewElem("description", GetText(x, "striphtml-description"))
.appendChild NewElem("link", GetText(x, "link"))
.appendChild NewElem("g:google_product_category", GetText(x, "product_type"))
.appendChild NewElem("g:price", GetText(x, "price"))
.appendChild NewElem("g:sale_price", GetText(x, "sale_price"))
.appendChild NewElem("g:brand", GetText(x, "brand"))
.appendChild NewElem("g:condition", GetText(x, "condition"))
.appendChild NewElem("g:expiration_date", GetText(x, "expiration_date"))
.appendChild NewElem("g:shipping_weight", GetText(x, "weight"))
.appendChild NewElem("g:mpn", GetText(x, "id"))
.appendChild NewElem("g:image_link", GetText(x, "image_link"))
.appendChild NewElem("g:availability", GetText(x, "availability"))
.appendChild NewElem("g:gtin", GetText(x, "upc"))
v = Split(Trim( GetText(x, "extra[normalize-space() != '']") ), "|")
If UBound(v) = 3 Then
vGender = v(0) : vAgeGroup = v(1) : vColor = v(2) : vSize = v(3)
Else
vGender = "" : vAgeGroup = "" : vColor = "" : vSize = ""
End If
.appendChild NewElem("g:gender", vGender)
.appendChild NewElem("g:age_group", vAgeGroup)
.appendChild NewElem("g:color", vColor)
.appendChild NewElem("g:size", vSize)
End With
Channel.appendChild NewItem
Next
' send the feed (saving the document to the Response object does this)
Response.ContentType = "text/xml; charset=UTF-8"
OutputDoc.save Response
' --- HELPER FUNCTIONS ------------------------------------------------------
Function NewElem(name, text)
Dim namespaceURI
If InStr(name, ":") Then
namespaceURI = Namespaces( Split(name, ":")(0) )
Set NewElem = OutputDoc.createNode(NODE_ELEMENT, name, namespaceURI)
Else
Set NewElem = OutputDoc.createElement(name)
End If
If text <> "" Then NewElem.text = text
End Function
Function GetText(context, xPath)
Dim node
Set node = context.selectSingleNode(xPath)
If node Is Nothing Then
GetText = ""
Else
GetText = node.text
End If
End Function
Подумайте об использовании более подходящего типа контента application/rss+xml
вместо text/xml