这不是一个问题,因为我已经找到了解决方案.我花了很多时间,这就是我想在这里解释的原因.
Msxml基于COM,因此即使你有有用的类来处理内存分配问题,它也不是很容易在C++中使用.但是编写一个新的XML解析器要困难得多,所以我想使用msxml.
问题:
我能够在互联网上找到足够的例子来帮助使用msxml CComPtr(智能指针避免必须手动调用每个IXMLDOMNode的Release()),CComBSTR(将C++字符串转换为字符串的COM格式)和CComVariant.这3个有用的课程是ATL课程,需要一个#include <atlbase.h>.
问题:Visual Studio 2008 Express(免费版)不包含ATL.
解:
使用comutil.h和comdef.h,包括一些简单的帮助程序类:
_bstr_t 或多或少取代 CComBSTR_variant_t 或多或少取代 CComVariant_com_ptr_tCComPtr通过使用间接取代_COM_SMARTPTR_TYPEDEF小例子:
#include <msxml.h>
#include <comdef.h>
#include <comutil.h>
// Define some smart pointers for MSXML
_COM_SMARTPTR_TYPEDEF(IXMLDOMDocument, __uuidof(IXMLDOMDocument)); // IXMLDOMDocumentPtr
_COM_SMARTPTR_TYPEDEF(IXMLDOMElement, __uuidof(IXMLDOMElement)); // IXMLDOMElementPtr
_COM_SMARTPTR_TYPEDEF(IXMLDOMNodeList, __uuidof(IXMLDOMNodeList)); // IXMLDOMNodeListPtr
_COM_SMARTPTR_TYPEDEF(IXMLDOMNamedNodeMap, __uuidof(IXMLDOMNamedNodeMap)); // IXMLDOMNamedNodeMapPtr
_COM_SMARTPTR_TYPEDEF(IXMLDOMNode, __uuidof(IXMLDOMNode)); // IXMLDOMNodePtr
void test_msxml()
{
// This program will use COM
CoInitializeEx(NULL, COINIT_MULTITHREADED);
{
// …Run Code Online (Sandbox Code Playgroud) 我有几个xml文件,其名称存储在另一个xml文件中.
我想使用xsl来生成xml文件组合的摘要.我记得有一种方法可以使用msxml扩展(我使用的是msxml).
我知道我可以使用每个文件的内容,select="document(filename)"但我不确定如何将所有这些文档合并为一个.
21 - 08年10月我应该提到,我想要做的合并XML进一步处理,所以它是不够的只是输出它的变换,我需要将其存储在一个变量设置节点.
给出以下XML:
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetMsisdnResponse xmlns="http://my.domain.com/">
<GetMsisdnResult>
<RedirectUrl>http://my.domain.com/cw/DoIdentification.do2?sessionid=71de6551fc13e6625194</RedirectUrl>
</GetMsisdnResult>
</GetMsisdnResponse>
</soap:Body>
</soap:Envelope>
Run Code Online (Sandbox Code Playgroud)
我试图在VBScript中使用XPath访问RedirectUrl元素:
set xml = CreateObject("MSXML2.DOMDocument")
xml.async = false
xml.validateOnParse = false
xml.resolveExternals = false
xml.setProperty "SelectionLanguage", "XPath"
xml.setProperty "SelectionNamespaces", "xmlns:s='http://my.domain.com/' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'"
err.clear
on error resume next
xml.loadXML (xmlhttp.responseText)
if (err.number = 0) then
redirectUrl = xml.selectSingleNode("/soap:Envelope/soap:Body/s:GetMsisdnResponse/s:GetMsisdnResult/s:RedirectUrl").text
end if
Run Code Online (Sandbox Code Playgroud)
但它找不到RedirectUrl节点,因此当我尝试获取.text属性时没有任何内容.我究竟做错了什么
我有一个经典ASP网站的VB6后端.然后,VB使用MSXML2.XMLHTTP在同一服务器上调用Web服务.这适用于我们所有的服务器但只有一个.如果我将Web服务站点设置为接受匿名登录,则它将起作用,但是如果我仅强制集成安全性,MSXML将返回"拒绝访问"错误.
Set objDom = CreateObject("MSXML2.DOMDocument")
Set objXmlHttp = CreateObject("MSXML2.XMLHTTP")
' Load XML
objDom.async = False
objDom.loadXML XmlBody
' Open the webservice
objXmlHttp.Open "POST", AsmxUrl, False
' Create headings
objXmlHttp.setRequestHeader "Content-Type", "text/xml; charset=utf-8"
objXmlHttp.setRequestHeader "SOAPAction", SoapActionUrl
' Send XML command
objXmlHttp.send objDom.xml
Run Code Online (Sandbox Code Playgroud)
编辑:根据AnthonyWJones的建议,我下了清单,它仍然无法正常工作.使用Fiddler,它显示一个具有401响应的请求.身份验证选项卡显示:
No Proxy-Authenticate Header is present.
WWW-Authenticate Header is present: Negotiate
WWW-Authenticate Header is present: NTLM
Run Code Online (Sandbox Code Playgroud)
我确实注意到了一种奇怪的行为.当我使用登录到远程桌面的用户的凭据来呼叫网站时,它将起作用.我得到谈判,挑战,然后200,它会工作.当用户通过远程桌面登录而不是其他时间登录时,为什么会这样做有什么想法?
我编写了一个VBScript,它应该遍历XML文件中的所有节点,而不管树的深度如何.除了不显示深度为2级或更高级别的节点的节点名称之外,它的效果很好.我需要节点名称和值,以便我有名称/值对供其他程序进一步处理.任何人都可以帮助我显示丢失的节点名称.
以下是我的代码:
<html>
<head>
</head>
<body>
<script type="text/vbscript">
Set xmlDoc=CreateObject("Microsoft.XMLDOM")
xmlDoc.async="false"
xmlDoc.load("test.xml")
Dim objDocElem, strNode, strSubNode, xmlnn, xmlnv, xmlnc, xmldd, xmlfd, xmlfv
Set n_firstchild = xmldoc.documentElement.firstChild
Set p_node = n_firstchild.parentNode
Set pn_attribs = p_node.attributes
For Each pnAttr in pn_attribs
xmlfd = xmlfd & pnAttr.name & chr(9)
xmlfv = xmlfv & pnAttr.value & chr(9)
Next
Set objDocElem=xmlDoc.documentElement
Set y = objDocElem.childNodes
i=0
Do While i < y.length
If y(i).nodeType <> 3 Then
If Isnull(y(i).childNodes(0).nodeValue) Then
xmlnv = …Run Code Online (Sandbox Code Playgroud) 我有一个经典的 ASP 页面,它正在读取外部 rss 提要(xml 文档),然后将其显示在网页上。在我的网站移到新服务器之前,这一切正常。我认为现在是 Windows 2008。我的脚本现在超时了。我不认为问题实际上是因为我增加了超时值而花费的时间太长。有谁知道问题可能是什么以及我如何解决它?
该网站托管在共享服务器上,因此我无法更改任何服务器设置。
我正在使用的代码是
Set objHTTP = Server.CreateObject("Msxml2.ServerXMLHTTP")
' resolve, connect, send, receive - in milliseconds
objhttp.setTimeouts 5000, 60000, 10000, 10000
objHTTP.open "GET",RSSURL,false
objHTTP.send
Run Code Online (Sandbox Code Playgroud)
该代码返回最后一行 (objHTTP.send) 的超时时间。“RSSURL”可以是任何外部 RSS 提要。我正在使用http://www.valewisham.org.uk/rss.xml进行测试。
可能每个Web开发人员都熟悉这样的模式:
var xmlHttp = null;
if (window.XMLHttpRequest) {
// If IE7, Mozilla, Safari, and so on: Use native object.
xmlHttp = new XMLHttpRequest();
}
else
{
if (window.ActiveXObject) {
// ...otherwise, use the ActiveX control for IE5.x and IE6.
xmlHttp = new ActiveXObject('MSXML2.XMLHTTP');
}
}
Run Code Online (Sandbox Code Playgroud)
但问题是 - 如果客户端的PC上有多个MSXML版本(假设是3.0,5.0,6.0),那么其中一个版本将由MSXML2.XMLHTTP调用选择(最后注意没有版本后缀)?它会是最新的还是 - 不一定?
还有一个问题 - 是否可以检查选择了哪个版本?
我有一些包含格式良好的 XML 的文本字符串。
我希望能够(1)将这些字符串转换为IXMLNodes(2)将它们附加到现有的XMLDocument. 最好不声明新的XMLDocument第一个。
这似乎不可能?
有没有什么简单的方法可以完成等效的事情?我最初的想法是使用IXMLNode.XML(string) 属性并插入新字符串。IXMLNode.XML只读则不然。
这是一个例子,如果我在 a 中有以下字符串TStringList,
<Property Name="Version" RttiType="tkString"></Property>
<Property Name="ShowSubunit" RttiType="tkBoolean"></Property>
Run Code Online (Sandbox Code Playgroud)
我有以下 XML,已加载到 中TXMLDocument,我如何轻松地将上面的两行附加到下面TXMLDocument?
<Program Name="PFOO">
<Class Name="CFOO">
<Property Name="DBN" RttiType="tkString"/>
<Property Name="SDate" RttiType="tkClass" ClassType="TXSDATE">12/30/1899</Property>
<Property Name="XForm" RttiType="tkEnumeration">xfXML</Property>
<Property Name="Singleton" RttiType="tkBoolean">True</Property>
</Class>
</Program>
Run Code Online (Sandbox Code Playgroud)
还有其他(简单)方法可以实现此目的(请不要对 XML 属性进行受保护的黑客攻击)?
谢谢你!
我有一些示例 XML,我在其中根据日期查询节点。
示例 XML 文档:
<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
<NewDataSet>
<Table>
<EmployeeBankGUID>dc396ebe-c8a4-4a7f-85b5-b43c1890d6bc</EmployeeBankGUID>
<ValidFromDate>2012-02-01T00:00:00-05:00</ValidFromDate>
</Table>
<Table>
<EmployeeBankGUID>2406a5aa-0246-4cd7-bba5-bb17a993042b</EmployeeBankGUID>
<ValidFromDate>2013-02-01T00:00:00-05:00</ValidFromDate>
</Table>
<Table>
<EmployeeBankGUID>2af49699-579e-4beb-9ab0-a58b4bee3158</EmployeeBankGUID>
<ValidFromDate>2014-02-01T00:00:00-05:00</ValidFromDate>
</Table>
</NewDataSet>
Run Code Online (Sandbox Code Playgroud)
所以基本上有三个日期:
使用 MSXML,我可以使用 XPath 查询按这些日期进行查询和过滤:
/NewDataSet/Table[ValidFromDate>"2013-02-12"]
Run Code Online (Sandbox Code Playgroud)
这有效,并返回一个IXMLDOMNodeList包含一个项目:
<Table>
<EmployeeBankGUID>2af49699-579e-4beb-9ab0-a58b4bee3158</EmployeeBankGUID>
<ValidFromDate>2014-02-01T00:00:00-05:00</ValidFromDate>
</Table>
Run Code Online (Sandbox Code Playgroud)
使用 MSXML 的 XPath 查询;Microsoft 在 1990 年代后期创建的 xml 变体,在 W3C 标准化为完全不同形式的 XPath 之前。
DOMDocument doc = new DOMDocument();
//...load the xml...
IXMLDOMNodeList nodes = doc.selectNodes('/NewDataSet/Table[ValidFromDate>"2013-02-12"]');
Run Code Online (Sandbox Code Playgroud)
但是那个版本的 MSXML 并不“符合标准”(因为它是在有标准之前创建的)。自 2005 年以来推荐的一种,遵循标准的一种,唯一具有我需要的功能的是 MSXML 6。 …
为了在Delphi(2007)程序中快速解析一些大型XML文档,我实现了IVBSAXContentHandler接口并使用它如下:
FXMLReader := CoSAXXMLReader60.Create;
FXMLReader.contentHandler := Self;
FXMLReader.parseURL(FXmlFile);
Run Code Online (Sandbox Code Playgroud)
这很好,只要我简单地解析整个文件,但是一旦找到了我要查找的内容,我就想停止.所以我的IVBSAXContentHandler.startElement实现会检查某些条件,当它为true时应该中止进一步的解析.我试过这个:
procedure TContentHandler.startElement(var strNamespaceURI, strLocalName, strQName: WideString; const oAttributes: IVBSAXAttributes);
begin
if SomeCondition then
SysUtils.Abort;
end;
Run Code Online (Sandbox Code Playgroud)
不幸的是,这引起了相当无益的EOleException"灾难性失败".(我也尝试使用相同的结果引发自定义异常.)
MSDN说如下:
ErrorHandler接口实质上允许XMLReader通知它想要中止处理的ContentHandler实现.相反,ContentHandler实现可以向XMLReader指示它想要中止处理.这可以通过简单地引发特定于应用程序的异常来实现.一旦实现找到它正在寻找的内容,这对于中止处理特别有用:
Private Sub IVBSAXContentHandler_characters(ByVal strChars As String)
' I found what I was looking for, abort processing
Err.Raise vbObjectError + errDone, "startElement", _
"I got what I want, let's go play!"
End Sub
Run Code Online (Sandbox Code Playgroud)
所以,显然我还需要以某种方式实现IVBSAXErrorHandler接口.该接口需要三种方法:
procedure TContentHandler.error(const oLocator: IVBSAXLocator;
var strErrorMessage: WideString; nErrorCode: Integer);
begin
end;
procedure TContentHandler.fatalError(const oLocator: IVBSAXLocator;
var strErrorMessage: WideString; nErrorCode: …Run Code Online (Sandbox Code Playgroud) msxml ×10
xml ×6
delphi ×2
vbscript ×2
xpath ×2
asp-classic ×1
c++ ×1
delphi-2007 ×1
javascript ×1
msxml6 ×1
namespaces ×1
rss ×1
sax ×1
txmldocument ×1
vb6 ×1
web-services ×1
xmldom ×1
xmlnode ×1
xmlnodelist ×1
xslt ×1