XML,NextSibling 我做 NodeAutoIndent。空(#9)节点问题
XML, NextSibling i doNodeAutoIndent. Empty (#9) nodes problem
我的代码是:
XmlDoc := NewXMLDocument;
with XmlDoc do
Options := Options + [doNodeAutoIndent];
[...]
N := Parent.ChildNodes.FindNode('KONTRAHENT');
while N <> nil do
begin
if N.ChildNodes['ID_KONTRAHENTA'].NodeValue = KontrNr then
DoSomething;
N := N.NextSibling;
end;
和XML像这样:
<KARTOTEKA_KONTRAHENTOW>
<KONTRAHENT>
<ID_KONTRAHENTA>925</ID_KONTRAHENTA>
</KONTRAHENT>
<KONTRAHENT>
<ID_KONTRAHENTA>1208</ID_KONTRAHENTA>
</KONTRAHENT>
</KARTOTEKA_KONTRAHENTOW>
在 Watch Parent.XML 中查看的数据如下:
'<KARTOTEKA_KONTRAHENTOW>'#$D#$A#9#9'<KONTRAHENT>'#$D#$A#9#9#9'<ID_KONTRAHENTA>925</ID_KONTRAHENTA>'#$D#$A#9#9'</KONTRAHENT>'#$D#$A#9#9'<KONTRAHENT>'#$D#$A#9#9#9'<ID_KONTRAHENTA>1208</ID_KONTRAHENTA>'#$D#$A#9#9'</KONTRAHENT>'#$D#$A#9'</KARTOTEKA_KONTRAHENTOW>'
当我在循环中读取节点时,设置选项:[doNodeAutoIndent]
然后我有一些这样的节点:N = '#$D#$A#9#9' 和节点数 = 7(而不是 2,在这个例子中)
没有 doNodeAutoIndent,一切正常,节点数 = 2,但我的 XML 文件在一行中:(
问题是:
如何在启用 doNodeAutoIndent 时绕过空的 NextSibling?
您所描述的完全正常。元素之间的空白被视为层次结构中的附加文本节点,例如,对于您的示例 XML,其 DOM 树如下所示:
KARTOTEKA_KONTRAHENTOW
|_ '#$D#$A#9#9'
|_ KONTRAHENT
| |_ '#$D#$A#9#9#9'
| |_ ID_KONTRAHENTA
| | |_ '925'
| |_ '#$D#$A#9#9'
|_ '#$D#$A#9#9'
|_ KONTRAHENT
| |_ '#$D#$A#9#9#9'
| |_ ID_KONTRAHENTA
| | |_ '1208'
| |_ '#$D#$A#9#9'
|_ '#$D#$A#9'
这就是节点数高于您预期的原因。
您需要在遍历元素时考虑这些额外的文本节点,例如:
N := Parent.ChildNodes.First;
while N <> nil do
begin
if (N.NodeType = ntElement) and (N.NodeName = 'KONTRAHENT') then
begin
if N.ChildNodes['ID_KONTRAHENTA'].NodeValue = KontrNr then
begin
// Do something with N ...
end;
end;
N := N.NextSibling;
end;
或者,使用 XPath 查询来只关注您真正需要的节点,例如:
uses
..., XmlIntf, XmlDom;
var
...
XPath: IDOMNodeSelect;
Nodes: IDOMNodeList;
N: IDOMNode;
I: Integer;
...
if Supports(Parent.DOMNode, IDOMNodeSelect, XPath) then
begin
Nodes := XPath.selectNodes('KONTRAHENT[ID_KONTRAHENTA='+IntToStr(KontrNr)+']');
for I := 0 to Nodes.length-1 do
begin
N := Nodes[i];
// do something with N ...
end;
end else
begin
// code shown above ...
end;
我的代码是:
XmlDoc := NewXMLDocument;
with XmlDoc do
Options := Options + [doNodeAutoIndent];
[...]
N := Parent.ChildNodes.FindNode('KONTRAHENT');
while N <> nil do
begin
if N.ChildNodes['ID_KONTRAHENTA'].NodeValue = KontrNr then
DoSomething;
N := N.NextSibling;
end;
和XML像这样:
<KARTOTEKA_KONTRAHENTOW>
<KONTRAHENT>
<ID_KONTRAHENTA>925</ID_KONTRAHENTA>
</KONTRAHENT>
<KONTRAHENT>
<ID_KONTRAHENTA>1208</ID_KONTRAHENTA>
</KONTRAHENT>
</KARTOTEKA_KONTRAHENTOW>
在 Watch Parent.XML 中查看的数据如下:
'<KARTOTEKA_KONTRAHENTOW>'#$D#$A#9#9'<KONTRAHENT>'#$D#$A#9#9#9'<ID_KONTRAHENTA>925</ID_KONTRAHENTA>'#$D#$A#9#9'</KONTRAHENT>'#$D#$A#9#9'<KONTRAHENT>'#$D#$A#9#9#9'<ID_KONTRAHENTA>1208</ID_KONTRAHENTA>'#$D#$A#9#9'</KONTRAHENT>'#$D#$A#9'</KARTOTEKA_KONTRAHENTOW>'
当我在循环中读取节点时,设置选项:[doNodeAutoIndent] 然后我有一些这样的节点:N = '#$D#$A#9#9' 和节点数 = 7(而不是 2,在这个例子中)
没有 doNodeAutoIndent,一切正常,节点数 = 2,但我的 XML 文件在一行中:(
问题是: 如何在启用 doNodeAutoIndent 时绕过空的 NextSibling?
您所描述的完全正常。元素之间的空白被视为层次结构中的附加文本节点,例如,对于您的示例 XML,其 DOM 树如下所示:
KARTOTEKA_KONTRAHENTOW
|_ '#$D#$A#9#9'
|_ KONTRAHENT
| |_ '#$D#$A#9#9#9'
| |_ ID_KONTRAHENTA
| | |_ '925'
| |_ '#$D#$A#9#9'
|_ '#$D#$A#9#9'
|_ KONTRAHENT
| |_ '#$D#$A#9#9#9'
| |_ ID_KONTRAHENTA
| | |_ '1208'
| |_ '#$D#$A#9#9'
|_ '#$D#$A#9'
这就是节点数高于您预期的原因。
您需要在遍历元素时考虑这些额外的文本节点,例如:
N := Parent.ChildNodes.First;
while N <> nil do
begin
if (N.NodeType = ntElement) and (N.NodeName = 'KONTRAHENT') then
begin
if N.ChildNodes['ID_KONTRAHENTA'].NodeValue = KontrNr then
begin
// Do something with N ...
end;
end;
N := N.NextSibling;
end;
或者,使用 XPath 查询来只关注您真正需要的节点,例如:
uses
..., XmlIntf, XmlDom;
var
...
XPath: IDOMNodeSelect;
Nodes: IDOMNodeList;
N: IDOMNode;
I: Integer;
...
if Supports(Parent.DOMNode, IDOMNodeSelect, XPath) then
begin
Nodes := XPath.selectNodes('KONTRAHENT[ID_KONTRAHENTA='+IntToStr(KontrNr)+']');
for I := 0 to Nodes.length-1 do
begin
N := Nodes[i];
// do something with N ...
end;
end else
begin
// code shown above ...
end;