📄 uxmlcommon.pas
字号:
{*******************************************************}
{ 软件名称: --通用-- }
{ 单元名称: 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 + -