⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uxmlcommon.pas

📁 抽象三层访问数据库示例
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{*******************************************************}
{       软件名称: --通用--                              }
{       单元名称: uXMLCommon.pas                        }
{       中文名称: XML文件解析助手类                     }
{       单元描述:                                       }
{       创    建: SamonHua                              }
{       创建日期: 2007-11-19                            }
{       修    改:                                       }
{       修改日期:                                       }
{       版权所有 (C)2002-2007 深圳壹平台信息技术有限公司}
{*******************************************************}
unit uXMLCommon;

interface

uses
  SysUtils, Classes, Variants, XMLIntf, XMLDoc, uCommon, MSXML2_TLB;
                                                  
type
  TXMLHelper = class
  private
    class function IsNodePath(NodePath: string; PathDelimiter: string = '.'): boolean;
  public
    class function GetParseIgnoreError: Boolean;
    class procedure SetParseIgnoreError(Value: Boolean);
    class function GetParseIgnoreCase: Boolean;
    class procedure SetParseIgnoreCase(Value: Boolean);
    //检查节点属性是否同输入参数匹配
    class function CheckAttributes(XMLNode: IXMLNode; const Attributes: string): boolean;
    //检查节点名称是否同输入参数匹配
    class function NodeNameEqual(XMLNode: IXMLNode; NodeName: string): boolean;
    //检查节点值是否同输入参数匹配
    class function NodeValueEqual(XMLNode: IXMLNode; NodeValue: string): boolean;
    //检查节点属性值是否同输入参数匹配
    class function AttributeEqual(XMLNode: IXMLNode; AttributeName, AttributeValue: string): boolean;
    //按节点路径返回节点,从顶级节点查找
    class function GetNode(XMLDocument: XMLIntf.IXMLDocument; NodePath: string;
      PathDelimiter: string = '.'): IXMLNode;
    //按节点路径返回符合条件的子节点
    class function GetChildNodeByPath(XMLNode: IXMLNode; NodePath: string;
      PathDelimiter: string = '.'): IXMLNode;
    //获取指定节点的指定节点名称的下级节点
    class function GetChildNode(XMLNode: IXMLNode; const NodeName: string;
      const NodeValue: string = ''; const AttributesOrChildNodePath: string = ''): IXMLNode;
    //获取指定节点名称的节点值
    class function GetChildNodeValue(XMLNode: IXMLNode; const NodeName: string;
      const AttributeName: string = ''): string;
    //获取指定节点值
    class function GetNodeValue(XMLNode: IXMLNode): string;
    //获取指定节点属性节点
    class function GetAttributeNode(XMLNode: IXMLNode; const AttributeName: string): IXMLNode;
    //获取指定节点的指定名称的属性值
    class function GetNodeAttributeValue(XMLNode: IXMLNode; const AttributeName: string): string;
    //检查有无指定节点名称的子节点
    class function HasChildNode(XMLNode: IXMLNode; const NodeName: string;
      const NodeValue: string = ''; const AttributesOrChildNodePath: string = ''): Boolean;
    //检查有无指定名称的属性
    class function HasAttribute(XMLNode: IXMLNode; const AttributeName: string): Boolean;
    //检查符合节点名称的子节点数量
    class function GetChildNodeCount(XMLNode: IXMLNode; const NodeName: string;
      const NodeValue: string = ''; const AttributesOrChildNodePath: string = ''): integer;
    //新建空的XML文件内容
    class function NewXMLDocument(Version: string = '1.0';
      Encoding: string = 'GBK'; RootNodeName: string = ''): XMLIntf.IXMLDocument;
    //生成新的节点
    class function CreateNode(XMLDocument: XMLIntf.IXMLDocument;
      const NodeName, NodeValue: string; const Attributes: string = ''): IXMLNode; overload;
    class function CreateNode(ParentNode: IXMLNode;
      const NodeName, NodeValue: string; const Attributes: string = ''): IXMLNode; overload;
    //为节点添加/修改属性
    class procedure AddAttributes(XMLNode: IXMLNode; const Attributes: string);
    //检查XML是否符合XSD
    class function XMLXSDValid(XSD, XML: WideString): boolean;
    //加载XML文件
    class function LoadXMLData(var XMLDocument: XMLIntf.IXMLDocument; XMLData: WideString;
      AutoCheckLastError: Boolean = true): boolean;
    class function LoadXMLDocument(var XMLDocument: XMLIntf.IXMLDocument; XMLFile: string;
      AutoCheckLastError: Boolean = true): boolean;
    class function DeleteChildNode(XMLNode: IXMLNode; const NodeName: string;
      const NodeValue: string = ''; const Attributes: string = ''): Boolean;
    class function DeleteNodeAttributes(XMLNode: IXMLNode;
      const Attributes: string): Boolean;
  end;

implementation

var
  //忽略解析错误
  ParseIgnoreError: Boolean;
  //忽略元素//属性大小写
  ParseIgnoreCase: boolean;

class function TXMLHelper.GetNode(XMLDocument: XMLIntf.IXMLDocument;
  NodePath, PathDelimiter: string): IXMLNode;
begin
  Result := GetChildNodeByPath(XMLDocument.DocumentElement, NodePath,
    PathDelimiter);
end;

class function TXMLHelper.GetChildNode(XMLNode: IXMLNode;
  const NodeName, NodeValue, AttributesOrChildNodePath: string): IXMLNode;
var
  i: integer;
  blnIsNodePath: Boolean;
begin
//AttributesOrChildNodePath: 子节点匹配条件,属性匹配条件列表或者需要包含的子节点匹配路径
//请参考IsNodePath方法参数说明
  Result := nil;
  if XMLNode = nil then
    exit;
  blnIsNodePath := IsNodePath(AttributesOrChildNodePath);
  for i := 0 to XMLNode.ChildNodes.Count - 1 do
    if NodeNameEqual(XMLNode.ChildNodes.Nodes[i], NodeName)
      and ((NodeValue = '') or NodeValueEqual(XMLNode.ChildNodes.Nodes[i], NodeValue)) then
      if (AttributesOrChildNodePath = '')
        or (blnIsNodePath and (GetChildNodeByPath(XMLNode.ChildNodes.Nodes[i], AttributesOrChildNodePath) <> nil))
        or ((not blnIsNodePath) and CheckAttributes(XMLNode.ChildNodes.Nodes[i], AttributesOrChildNodePath)) then
      begin
        Result := XMLNode.ChildNodes.Nodes[i];
        break;
      end;
end;

class function TXMLHelper.GetChildNodeValue(XMLNode: IXMLNode; const NodeName,
  AttributeName: string): string;
var
  tmpNode: IXMLNode;
begin
  SetLastErrorInfo;
  Result := '';
  tmpNode := GetChildNode(XMLNode, NodeName);
  if tmpNode = nil then
  begin
    if not GetParseIgnoreError then
      SetLastErrorInfo('节点元素不存在。');
    exit;
  end;
  result := GetNodeAttributeValue(tmpNode, AttributeName);
end;

class function TXMLHelper.GetNodeValue(XMLNode: IXMLNode): string;
begin
  SetLastErrorInfo;
  case XMLNode.NodeType of
    ntAttribute: result := VarToStrDef(XMLNode.NodeValue, '');
  else
    if XMLNode.IsTextElement then
      result := XMLNode.Text
    else
      if GetParseIgnoreError then
        Result := ''
      else
      begin
        SetLastErrorInfo('非简单文本节点元素。');
        Exit;
      end;
  end;
end;

class function TXMLHelper.GetNodeAttributeValue(XMLNode: IXMLNode;
  const AttributeName: string): string;
var
  tmpNode: IXMLNode;
begin
  SetLastErrorInfo;
  if AttributeName = '' then
    Result := GetNodeValue(XMLNode)
  else
  begin
    tmpNode := GetAttributeNode(XMLNode, AttributeName);
    if tmpNode <> nil then
      result := GetNodeValue(tmpNode)
    else
      if not GetParseIgnoreError then
      begin
        SetLastErrorInfo('节点元素不存在属性 %s。', [AttributeName]);
        Exit;
      end;
  end;
end;

class function TXMLHelper.GetAttributeNode(XMLNode: IXMLNode;
  const AttributeName: string): IXMLNode;
var
  i: integer;
begin
  Result := nil;
  for i := 0 to XMLNode.AttributeNodes.Count - 1 do
    if NodeNameEqual(XMLNode.AttributeNodes.Nodes[i], AttributeName) then
    begin
      Result := XMLNode.AttributeNodes.Nodes[i];
      break;
    end;
end;

class function TXMLHelper.GetChildNodeByPath(XMLNode: IXMLNode;
  NodePath, PathDelimiter: string): IXMLNode;
var
  XMLChildNode: IXMLNode;
  strNodeName, strNodeValue, strAttributes: string;
  i: Integer;
begin
//PathDelimiter: 节点路径分隔符.缺省设置为".",不能为或者包含"="、";"、"&"等字符
  Result := nil;
  if (XMLNode = nil) or (NodePath = '') then
    exit;
  XMLChildNode := XMLNode;
  for i := 0 to SubStrCount(NodePath, PathDelimiter) do
  begin
    strNodeName := CopySubStr(NodePath, i, PathDelimiter);
    strAttributes := CopySubStr(strNodeName, 1, '&');
    strNodeName := CopySubStr(strNodeName, 0, '&');
    strNodeValue := CopySubStr(strNodeName, 1, '=');
    strNodeName := CopySubStr(strNodeName, 0, '=');
    XMLChildNode := GetChildNode(XMLChildNode, strNodeName, strNodeValue, strAttributes);
    if XMLChildNode = nil then
      break;
  end;
  Result := XMLChildNode;
end;

class function TXMLHelper.CheckAttributes(XMLNode: IXMLNode;
  const Attributes: string): boolean;
var
  i: integer;
  strAttName, strAttValue: string;
  tmpAttNode: IXMLNode;
begin
  Result := true;
  for i := 0 to SubStrCount(Attributes) do
  begin
    strAttName := CopySubStr(Attributes, i);
    strAttValue := CopySubStr(strAttName, 1, '=');
    strAttName := CopySubStr(strAttName, 0, '=');
    tmpAttNode := GetAttributeNode(XMLNode, strAttName);
    Result := Result and (tmpAttNode <> nil)
      and NodeValueEqual(tmpAttNode, strAttValue);
    if not Result then
      break;
  end;
end;

class function TXMLHelper.HasAttribute(XMLNode: IXMLNode;
  const AttributeName: string): Boolean;
begin
  if ParseIgnoreCase then
    Result := GetAttributeNode(XMLNode, AttributeName) <> nil
  else
    Result := XMLNode.HasAttribute(AttributeName);
end;

class function TXMLHelper.HasChildNode(XMLNode: IXMLNode;
  const NodeName, NodeValue, AttributesOrChildNodePath: string): Boolean;
begin
  Result := GetChildNode(XMLNode, NodeName, NodeValue, AttributesOrChildNodePath) <> nil;
end;

class function TXMLHelper.GetChildNodeCount(XMLNode: IXMLNode;
  const NodeName, NodeValue, AttributesOrChildNodePath: string): integer;
var
  i: integer;
  blnIsNodePath: Boolean;
begin
//参数请参考GetChildNodeByPath方法说明
  Result := 0;
  blnIsNodePath := IsNodePath(AttributesOrChildNodePath);
  for i := 0 to XMLNode.ChildNodes.Count - 1 do
    if NodeNameEqual(XMLNode.ChildNodes.Nodes[i], NodeName)
      and ((NodeValue = '') or NodeValueEqual(XMLNode.ChildNodes.Nodes[i], NodeValue)) then
      if (AttributesOrChildNodePath = '')
        or (blnIsNodePath and (GetChildNodeByPath(XMLNode.ChildNodes.Nodes[i], AttributesOrChildNodePath) <> nil))
        or ((not blnIsNodePath) and CheckAttributes(XMLNode.ChildNodes.Nodes[i], AttributesOrChildNodePath)) then
        inc(Result);
end;

class function TXMLHelper.GetParseIgnoreCase: Boolean;
begin
  Result := ParseIgnoreCase;
end;

class function TXMLHelper.GetParseIgnoreError: Boolean;
begin
  Result := ParseIgnoreError;
end;

class procedure TXMLHelper.SetParseIgnoreCase(Value: Boolean);
begin
  ParseIgnoreCase := Value;
end;

class procedure TXMLHelper.SetParseIgnoreError(Value: Boolean);
begin
  ParseIgnoreError := Value;
end;

class function TXMLHelper.IsNodePath(NodePath, PathDelimiter: string): boolean;
begin
//NodePath:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -