有一个xml的数据文件。其对应的dtd文件中对所有的属性定义全部是CDATA,数据文件中所有属性的内容全部用双引号包含(不好意思,不太懂xml不知道是不是所有的字段内容都要引号的)。
现在检测出其中属性内容凡是中文或者只有一个0的,统统检测为varNull类型的variant,这是为什么?
难道数字或者英文跟中文字符在variant单元中被判定的类型还不一样的?
现在检测出其中属性内容凡是中文或者只有一个0的,统统检测为varNull类型的variant,这是为什么?
难道数字或者英文跟中文字符在variant单元中被判定的类型还不一样的?
↑検査你的xml文件encoding、再看dtd文件的内容。
都可用「XML Mapping」工具査看検測。
这个有影响吗?
两者的区别是打印函数中我用了...node[i].nodevalue,而检测函数中因为要确定是哪一个属性,用了...node['str'].nodevalue。
当检测出类型为varNull,即检测函数中直接赋值给一个字符串要出错的情况下,我可以用打印函数把整个节点和那个属性的类型打印出来(打印函数中肯定是要读取那个属性的内容的)
另外我在检测函数中用indexof先取索引,然后再用node[i]的形式来取数还是不行,郁闷,不知道原因了撒
写明目的(NI要的結果)...
Help you up!
<?xml version="1.0" encoding="GBK"?><!ELEMENT SCHEMA (SWJG)>
<!ATTLIST SCHEMA
NAME CDATA #REQUIRED
CHSNAME CDATA #REQUIRED
SSSQ CDATA #REQUIRED
CRC CDATA #REQUIRED
>
<!ELEMENT SWJG (SWJG+ | TAXPAYER*)>
<!ATTLIST SWJG
SWJGID CDATA #REQUIRED
SWJGMC CDATA #REQUIRED
HZRQ CDATA #REQUIRED
RECORDCOUNT CDATA #REQUIRED
>
<!--以下部分与YSFPCGLJK.DTD同-->
<!ELEMENT TAXPAYER (Records)>
<!--TAXPAYER属性部分由系统统一定义-->
<!ATTLIST TAXPAYER
SWSBH CDATA #REQUIRED
NSRMC CDATA #REQUIRED
SBRQ CDATA #REQUIRED
RECORDCOUNT CDATA #REQUIRED
CJLX CDATA #REQUIRED
CJRDM CDATA #REQUIRED
CJRMC CDATA #REQUIRED
>
<!ELEMENT Records (Record)*>
<!ELEMENT Record EMPTY>
<!ATTLIST Record
FPHM CDATA #REQUIRED
KPRQ CDATA #REQUIRED
KPJE CDATA #REQUIRED
XFSWSBH CDATA #REQUIRED
XFNSRMC CDATA #REQUIRED
GFSWSBH CDATA #REQUIRED
GFNSRMC CDATA #REQUIRED
>
------------------------------------------------------------
再贴我的两个函数的代码出来
GetNodeStr函数就是复原出一个节点的文本
function TForm1.GetNodeStr(inode:IXMLNode):string;
var
icount:integer;
value:string;
begin
icount:=0;
result:='<'+inode.NodeName;
while icount<inode.AttributeNodes.Count do
begin
if inode.AttributeNodes.Nodes[icount].NodeValue<>Null then value:=inode.AttributeNodes.Nodes[icount].NodeValue;
result := result + ' ' + inode.AttributeNodes.Nodes[icount].NodeName+'="'+value + '"';
inc(icount);
end;
result := result + '>';
end;checknode函数是递归调用检查所有数据合法性:
procedure TForm1.checknode(inode:IXMLNode);
var
nullvalue:boolean;
Nodestr,temp,GFSWSBH,XFSWSBH,fphm:string;
i:integer;
begin
nullvalue:=False;
Nodestr:=inode.NodeName;
if Nodestr='SWJG' then
begin
//机关代码位数不为6,7,9,11位的,且头几位代码匹配,错误号:1
Nodestr:=inode.AttributeNodes.Nodes['SWJGID'].NodeValue;
if not(
((length(Nodestr)=6) and (AnsiMidStr(Nodestr,1,2)='33')) or
((length(Nodestr)=7) and (AnsiMidStr(Nodestr,1,3)='233')) or
((length(Nodestr)=9) and (AnsiMidStr(Nodestr,1,3)='233')) or
((length(Nodestr)=11) and (AnsiMidstr(Nodestr,1,3)='233'))
)
then
begin
temp:=ErrInsertstr(inode,1);
ADOConn.Execute(temp);
end;
end
else if Nodestr='TAXPAYER' then
begin
//检查合法性
end
else if UpperCase(Nodestr)='RECORD' then
begin
//先把NodeValue为空的情况剔除,NodeValue为空对字符串赋值会出错
if inode.AttributeNodes.Nodes['GFSWSBH'].NodeValue=Null then
begin
showmessage(GetNodeStr(inode));//这里算是示例,就在这里调用getnodestr获取inode节点信息
nullvalue:=true;
ADOConn.Execute(ErrInsertStr(inode,2))
end
{ else if inode.AttributeNodes.Nodes['XFSWSBH'].NodeValue=Null then
begin
nullvalue:=true;
ADOConn.Execute(ErrInsertStr(inode,3))
end}
else if inode.AttributeNodes.Nodes['FPHM'].NodeValue=Null then
begin
nullvalue:=true;
ADOConn.Execute(ErrInsertStr(inode,4))
end; if not nullvalue then
begin
//购方纳税人识别号位数错误,不是15或者18位
//就是下面这条语句,如果没有上面=Null的判断,碰到是中文或者其他我不清楚的数据会报错,
//检测属性值为varNull,即不可识别。但是我在上面那几句判断=Null的语句里面
//加showmessage(GetNodeStr(inode));可以打印出节点的完整信息。但是这里我先用
//indexof('str')的方法获取一个gi索引,在用...Nodes[gi].NodeValue取值还是不行
//就是说同样的节点,在这个函数里面判断为varNull,但是在GetNodeStr函数里面就不是varNull类型
//可以很顺利的取值,然后构造字符串
GFSWSBH:=inode.AttributeNodes.Nodes['GFSWSBH'].NodeValue;
if (length(trim(GFSWSBH))<>15) and (length(trim(GFSWSBH))<>18) then
begin
temp:=ErrInsertStr(inode,2);
ADOConn.Execute(temp);
end;
//销方纳税人识别号超长
{ XFSWSBH:=inode.AttributeNodes.Nodes['XFSWSBH'].NodeValue;
if {(length(XFSWSBH)=0) or (length(XFSWSBH)>30) then
begin
temp:=ErrInsertStr(inode,3);
ADOConn.Execute(temp);
end;}
//发票号码为空
fphm:=inode.AttributeNodes.Nodes['FPHM'].NodeValue;
if length(fphm)=0 then
begin
temp:=ErrInsertStr(inode,4);
ADOConn.Execute(temp);
end;
end;
end;// if test then showmessage(booltostr(test));
for i:=0 to inode.ChildNodes.Count - 1 do
checknode(inode.ChildNodes.Nodes[i]);
end;