【问题标题】:XML, NextSibling i doNodeAutoIndent. Empty (#9) nodes problemXML,NextSibling 我做NodeAutoIndent。空(#9)节点问题
【发布时间】:2020-12-18 14:28:41
【问题描述】:

我的代码是:

  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>'

当我在循环中读取节点时,设置了 Options: [doNodeAutoIndent] 然后我有一些这样的节点:N = '#$D#$A#9#9' 和节点数 = 7(而不是 2,在这个例子中)

没有 doNodeAutoIndent,一切正常,节点数 = 2,但我的 XML 文件在一行中 :(

问题是: 启用doNodeAutoIndent时如何绕过空的NextSibling?

【问题讨论】:

  • 好的,但问题出在哪里?
  • 谢谢。我正在考虑它,但我没有注意到我没有问这个问题。问题是:“启用 doNodeAutoIndent 时如何绕过空的 NextSibling?”

标签: xml delphi nextsibling


【解决方案1】:

您所描述的是完全正常的。元素之间的空白被视为层次结构中的附加文本节点,例如,对于您的示例 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;

【讨论】:

  • 谢谢你,@remy-lebeau
猜你喜欢
  • 1970-01-01
  • 2015-11-11
  • 2020-05-13
  • 2019-01-29
  • 1970-01-01
  • 2012-07-02
  • 1970-01-01
  • 2012-02-14
  • 1970-01-01
相关资源
最近更新 更多