嘿,从帖子请求我得到一个xml文件的响应。 例如
'<?xml version="1.0" encoding="UTF-8" ?>'#$D#$A'<PosXML version="6.0.2">'#$D#$A#9'<ShowInfoResponse>'#$D#$A#9#9'<ReturnCode>0</ReturnCode>'#$D#$A#9'</ShowInfoResponse>'#$D#$A'</PosXML>'
问题是我如何纠正,因为我需要将它发送到LoadXMLData('Here');
以下是代码:
procedure TForm1.Button3Click(Sender: TObject);
var
xmldocument1:ixmldocument;
responseNode:ixmlnode;
test:string;
begin
xmldocument1 := loadxmldata('<?xml version="1.0" encoding="UTF-8" ?>'#$D#$A'<PsXML>'#$D#$A#9'<ShowInfo>'#$D#$A#9#9'<Code>1234</Code>'#$D#$A#9'</ShowInfo>'#$D#$A'</PsXML>');
responsenode := xmldocument1.DocumentElement.childnodes.Findnode('Code');
test := responsenode.ChildNodes[0].Text;
问题是test(string)总是会产生异常,因为responsenode是零。 提前谢谢!
答案 0 :(得分:4)
您错误地认为您的XML存在问题。
DocumentElement
属性为您提供对PsXML
或PosXML
节点的引用。读取该属性的ChildNodes
属性会为您提供该节点的子节点列表。但是,该列表只包含一个元素,ShowInfo
节点或ShowInfoResponse
。在该列表上调用FindNode
只能为您提供其中一个值。 它不会搜索列表中节点的子节点。由于文档元素没有子Code
元素,FindNode
正确返回nil
。
我怀疑你对调试器感到困惑。您的程序从网络中获取了某些内容,并将其存储在字符串中。您正在使用调试器来查看该字符串中的内容,并且调试器向您显示带有一堆数字符号和美元符号的内容,您确定不应该在那里。您的代码没有选择正确的节点,因此您得出结论,混乱的XML字符串必须是原因。
但XML是正确的。而且它甚至已经打印出来了!它有换行符和制表符来缩进。但调试器想要显示一个明确的字符串。如果它显示了一个实际的多行字符串和缩进的东西,那么你作为程序员就不会知道字符串中的真正内容。相反,调试器会显示无法显示的字符的数字字符代码。回车符和换行符分别具有数值13和10,以十六进制表示D和A.调试器使用Delphi自己的字符串文字格式显示值;数字字符文字引入了#
符号,后跟字符的数字代码。 $
表示该数字为十六进制。
答案 1 :(得分:3)
要“漂亮打印”XML代码,您可以使用Delphi函数FormatXMLData。但是,LoadXMLData并没有为人类可读性提供奖励积分,因此原始字符串就可以了。
答案 2 :(得分:1)
此字符串适用于LoadXMLData而无需更改。白色空间和回车等事情被忽略了。
答案 3 :(得分:0)
你正在寻找错误的节点,这就是它返回nil的原因。你必须寻找'ReturnCode'而不是'Code'。
答案 4 :(得分:0)
我认为你的问题是Code是ShowInfoResponse的Child节点。那怎么样:
responsenode := xmldocument1.DocumentElement.childnodes[0];
test := responsenode.ChildNodes['Code'].Text;
答案 5 :(得分:0)
IXMLNodeList.FindNode方法仅在列表中包含的节点上查找搜索NodeName,而不在子节点中查找。
如果您想要查看整个树,请使用此功能:
function RecursiveFindNode(ANode: IXMLNode; const SearchNodeName: string): IXMLNode;
var
I: Integer;
begin
if CompareText(ANode.NodeName, SearchNodeName) = 0 then
Result := ANode
else if not Assigned(ANode.ChildNodes) then
Result := nil
else begin
for I := 0 to ANode.ChildNodes.Count - 1 do
begin
Result := RecursiveFindNode(ANode.ChildNodes[I], SearchNodeName);
if Assigned(Result) then
Exit;
end;
end;
end;
然后,做这样的事情:
var
I: Integer;
ANode: IXMLNode;
begin
xmldocument1 := loadxmldata('<?xml version="1.0" encoding="UTF-8" ?>'#$D#$A'<PsXML>'#$D#$A#9'<ShowInfo>'#$D#$A#9#9'<Code>1234</Code>'#$D#$A#9'</ShowInfo>'#$D#$A'</PsXML>');
ANode := RecursiveFindNode(xmlDocument1.DocumentElement, 'Code'); //or ReturnCode if you use the first version of the XML
if Assigned(ANode) then
ShowMessage('Eureka!');
end;
警告以这种方式查找节点的效率非常低。如果您可以预见文档结构,最好使用该知识来导航文档并仅在需要时使用搜索。