Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / IXMLDOMDocument3 validatenode в delphi7 не работает / 7 сообщений из 7, страница 1 из 1
17.03.2020, 13:04
    #39938213
evgen29
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IXMLDOMDocument3 validatenode в delphi7 не работает
Здравствуйте! Валидировал свой xml с помощью xsd-схемы и объекта IXMLDOMDocument3 метод validate . Нормально валидировалось или выдавало ошибку. Но возникла необходимость удалять строки, в которых есть несоответствие xsd-схеме. Доходит до vXMLParserError :=vXMLDoc.validateNode(line);
и выдает ошибку EOleException with message 'Неизвестное имя'

Код
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
function TfrmSetFormat.ValidatePrice(f: string): boolean;
var
  vXMLParserError: IXMLDOMParseError;
  vXMLSchema: IXMLDOMSchemaCollection2;
  vXMLDoc: IXMLDOMDocument3;
  vXMLSchemaDoc: IXMLDOMDocument3;
  vStrs: TStringList;
  i, j: integer;
  str: string;
  line: IXMLDOMNode;
  lines: IXMLDOMNodeList;
  ws: Widestring;
begin
  result := false;
  vStrs := TStringList.Create();
  try
    //Загрузка схемы
    vXMLSchema := CoXMLSchemaCache60.Create();
    vXMLSchemaDoc := CoDOMDocument60.Create();
    vXMLSchemaDoc.async:=False;
    //vXMLSchemaDoc.load(localdir + 'farmsm\' + formattypedir + '\out.xsd');
    vStrs.LoadFromFile(localdir + 'farmsm\' + formattypedir + '\out.xsd');
    ws:=StringReplace(UTF8Decode(vStrs.Text),#13#10,'',[rfReplaceAll,rfIgnoreCase]);

    vXMLSchemaDoc.loadXML(ws);
    if vXMLSchemaDoc.parseError.errorCode <> 0 then
    begin
      ShowMessage(Format('Ошибка при загрузке схемы <%s: %s>', [vXMLSchemaDoc.parseError.reason, vXMLSchemaDoc.parseError.srcText]));
      Exit;
    end;
    vXMLSchema.add('', vXMLSchemaDoc);

    //Загрузка документа
    vXMLDoc := CoDOMDocument60.Create();
    vXMLDoc.async := False;
    vXMLDoc.resolveExternals := false;
    vXMLDoc.validateOnParse := false;
    //vXMLDoc.load(f);
    vStrs.Clear;
    vStrs.LoadFromFile(f);
    vStrs.Text:='<?xml version="1.0" encoding="UTF-8"?>'+vStrs.Text;
    ws:=UTF8Decode(vStrs.Text);
    vXMLDoc.loadXML(ws);

    vXMLDoc.schemas := vXMLSchema;

    lines := vXMLDoc.getElementsByTagName('line');
    line := lines.nextNode;
    j := 0;
    i := 0;
    while line <> nil do
    begin
      vXMLParserError := vXMLDoc.validateNode(line);
      if vXMLParserError<>nil then
      begin
      if vXMLParserError.errorCode <> 0 then
      begin
        str := Format('Ошибка при валидации <Причина: %s; Текст: %s; Код: %d>', [Trim(vXMLParserError.reason),
          vXMLParserError.srcText, vXMLParserError.errorCode]);
        vXMLDoc.removeChild(line);
        j := j + 1;
      end;
      end;
      i := i + 1;
      line := lines.nextNode;
    end;

    if vXMLDoc.getElementsByTagName('line').length = 0 then
      ShowMessage(Format('Все строки содержат ошибки. Последняя ошибка: %s', [str]))
    else
    begin
      ShowMessage(Format('Удалено %d строк с ошибками, осталось %d строк. Последняя ошибка: %s', [j, i - j, str]));
      ShowMessage('Валидация документа прошла успешно');
      result := true;
    end;
  finally
    FreeAndNil(vStrs);
  end;
end;



xsd-схема:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="output" type="outputType">
  </xs:element>

  <xs:complexType name="outputType">
    <xs:sequence>
      <xs:element name="header" type="headerType"/>
      <xs:element name="body" type="bodyType"/>
    </xs:sequence>    
  </xs:complexType>
  
  <xs:complexType name="headerType">
    <xs:all>
    </xs:all>    
  </xs:complexType>
  <xs:complexType name="bodyType">
    <xs:sequence minOccurs="1" maxOccurs="unbounded">
      <xs:element name="line" type="lineBodyType"/>
    </xs:sequence>   
  </xs:complexType>
  
  <xs:complexType name="lineBodyType">
    <xs:all>
	  <!--Секция описания прайс-листа-->
      <xs:element name="CODEPST" type="CType24" minOccurs="0" maxOccurs="1"/>
      <xs:element name="NAME" type="CType128" minOccurs="0" maxOccurs="1"/>
      <xs:element name="PROD" type="CType64" minOccurs="0" maxOccurs="1"/>
      <xs:element name="COUNTRY" type="CType32" minOccurs="0" maxOccurs="1"/>
      <xs:element name="MINZAK" type="NType9" minOccurs="0" maxOccurs="1"/>
      <xs:element name="MINKRATN" type="NType9" minOccurs="0" maxOccurs="1"/>
      <xs:element name="VALID" type="CType10" minOccurs="0" maxOccurs="1"/>
      <xs:element name="OSTATOK" type="NType9" minOccurs="0" maxOccurs="1"/>
      <xs:element name="EAN13" type="CType13" minOccurs="0" maxOccurs="1"/>
      <xs:element name="GNVLS" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
      <xs:element name="EDUP" type="CType12" minOccurs="0" maxOccurs="1"/>
      <xs:element name="PACK" type="NType9" minOccurs="0" maxOccurs="1"/>
      <xs:element name="REGPR" type="NType15_4" minOccurs="0" maxOccurs="1"/>
      <xs:element name="PRODPR" type="NType15_4" minOccurs="0" maxOccurs="1"/>
      <xs:element name="VAT" type="NType9" minOccurs="0" maxOccurs="1"/>
      <xs:element name="MARKER" type="CType16" minOccurs="0" maxOccurs="1"/>
      <xs:element name="PRICE" type="NType15_4" minOccurs="1" maxOccurs="1"/>
      <xs:element name="UID" type="CType50" minOccurs="0" maxOccurs="1"/>
    </xs:all>    
  </xs:complexType>  
  
   <xs:simpleType name="NType">
      <xs:restriction base="xs:decimal">
         <xs:minInclusive value="0"/>
		 <xs:fractionDigits value="0"/>
      </xs:restriction>
   </xs:simpleType>    
   <xs:simpleType name="NType15_4">
      <xs:restriction base="xs:string">
         <xs:pattern value="[+-]?\d{1,15}([.,]\d{1,4})?"/>
         <xs:maxLength value="21"/>
      </xs:restriction>
   </xs:simpleType>        
   <xs:simpleType name="NType8_4">
      <xs:restriction base="xs:string">
         <xs:pattern value="[+-]?\d{1,8}([.,]\d{1,4})?"/>
         <xs:maxLength value="14"/>
      </xs:restriction>
   </xs:simpleType>          
   <xs:simpleType name="NType10">
      <xs:restriction base="NType">
         <xs:maxInclusive value="999999999"/>
		 <xs:totalDigits value="9"/>
      </xs:restriction>
   </xs:simpleType>     
   <xs:simpleType name="NType9">
      <xs:restriction base="NType">
         <xs:maxInclusive value="999999999"/>
		 <xs:totalDigits value="9"/>
      </xs:restriction>
   </xs:simpleType>  
   <xs:simpleType name="NType5">
      <xs:restriction base="NType">
         <xs:maxInclusive value="99999"/>
		 <xs:totalDigits value="5"/>
      </xs:restriction>
   </xs:simpleType>  
   <xs:simpleType name="NType3">
      <xs:restriction base="NType">
         <xs:maxInclusive value="999"/>
		 <xs:totalDigits value="3"/>
      </xs:restriction>
   </xs:simpleType>     
   <xs:simpleType name="NType2">
      <xs:restriction base="NType">
         <xs:maxInclusive value="99"/>
		 <xs:totalDigits value="2"/>
      </xs:restriction>
   </xs:simpleType>  
   <xs:simpleType name="NType1">
      <xs:restriction base="NType">
         <xs:maxInclusive value="9"/>
		 <xs:totalDigits value="1"/>
      </xs:restriction>
   </xs:simpleType>  
   <xs:simpleType name="DType">
      <xs:restriction base="xs:string">
         <xs:pattern value="\d{2}[.]\d{2}[.]\d{4}"/>
         <xs:maxLength value="10"/>	  
      </xs:restriction>
   </xs:simpleType>  
   <xs:simpleType name="TType">
      <xs:restriction base="xs:time">
         <xs:pattern value="hh:mm:ss"/>
      </xs:restriction>
   </xs:simpleType>     
   <xs:simpleType name="CType2">
      <xs:restriction base="xs:string">
         <xs:minLength value="0"/>
         <xs:maxLength value="2"/>
      </xs:restriction>
   </xs:simpleType>     
   <xs:simpleType name="CType16">
      <xs:restriction base="xs:string">
         <xs:minLength value="0"/>
         <xs:maxLength value="16"/>
      </xs:restriction>
   </xs:simpleType>        
   <xs:simpleType name="CType8">
      <xs:restriction base="xs:string">
         <xs:minLength value="0"/>
         <xs:maxLength value="8"/>
      </xs:restriction>
   </xs:simpleType>        
   <xs:simpleType name="CType24">
      <xs:restriction base="xs:string">
         <xs:minLength value="0"/>
         <xs:maxLength value="24"/>
      </xs:restriction>
   </xs:simpleType>           
   <xs:simpleType name="CType64">
      <xs:restriction base="xs:string">
         <xs:minLength value="0"/>
         <xs:maxLength value="64"/>
      </xs:restriction>
   </xs:simpleType>           
   <xs:simpleType name="CType128">
      <xs:restriction base="xs:string">
         <xs:minLength value="0"/>
         <xs:maxLength value="128"/>
      </xs:restriction>
   </xs:simpleType>           
   <xs:simpleType name="CType254">
      <xs:restriction base="xs:string">
         <xs:minLength value="0"/>
         <xs:maxLength value="254"/>
      </xs:restriction>
   </xs:simpleType>              
   <xs:simpleType name="CType32">
      <xs:restriction base="xs:string">
         <xs:minLength value="0"/>
         <xs:maxLength value="32"/>
      </xs:restriction>
   </xs:simpleType>      
   <xs:simpleType name="CType12">
      <xs:restriction base="xs:string">
         <xs:minLength value="0"/>
         <xs:maxLength value="12"/>
      </xs:restriction>
   </xs:simpleType>       
   <xs:simpleType name="CType13">
      <xs:restriction base="xs:string">
         <xs:minLength value="0"/>
         <xs:maxLength value="13"/>
      </xs:restriction>
   </xs:simpleType>              
   <xs:simpleType name="CType10">
      <xs:restriction base="xs:string">
         <xs:minLength value="0"/>
         <xs:maxLength value="10"/>
      </xs:restriction>
   </xs:simpleType>       
   <xs:simpleType name="CType50">
      <xs:restriction base="xs:string">
         <xs:minLength value="0"/>
         <xs:maxLength value="50"/>
      </xs:restriction>
   </xs:simpleType>  

   <xs:simpleType name="Currency">
      <xs:restriction base="xs:string">
         <xs:enumeration value="USD"/>
         <xs:enumeration value="EUR"/>
      </xs:restriction>
   </xs:simpleType>   
</xs:schema>  



сам xml:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
<output><header></header><body>
<line><NAME>Курносики Бальзам для детей и взрослых "Пантенол ZD" , 75 мл.</NAME><COUNTRY>РОССИЯ</COUNTRY><PROD>ЗАО "Зеленая дубрава"</PROD>
<OSTATOK>9</OSTATOK><VALID>01.01.2022</VALID><PRICE>91.99</PRICE><EAN13>4605658403133</EAN13><CODEPST>40313</CODEPST>
</line>
<line><NAME>Курносики Бальзам для детей и взрослых "Пантенол ZD" , 75 мл.</NAME><COUNTRY>РОССИЯ</COUNTRY><PROD>ЗАО "Зеленая дубрава"</PROD>
<OSTATOK>24</OSTATOK><VALID>01.07.2022</VALID><PRICE>91.99</PRICE><EAN13>4605658403133</EAN13><CODEPST>40313</CODEPST></line>
...
</body></output>
...
Рейтинг: 0 / 0
17.03.2020, 14:25
    #39938273
goldmi45
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IXMLDOMDocument3 validatenode в delphi7 не работает
evgen29,

А если посмотреть, что в lines и в line, может тогда будет понятней, почему возникает ошибка?
...
Рейтинг: 0 / 0
17.03.2020, 16:26
    #39938342
evgen29
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IXMLDOMDocument3 validatenode в delphi7 не работает
goldmi45
evgen29,

А если посмотреть, что в lines и в line, может тогда будет понятней, почему возникает ошибка?


так validate проходит нормально, даже если я не убираю ошибки. vXMLParserError.errorCode просто не 0 становится и есть описание ошибки.
Попробовал на документе, где нет ошибок. Validate проходит, validatenode опять тоже самое. Не в этом дело.
...
Рейтинг: 0 / 0
17.03.2020, 17:13
    #39938371
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IXMLDOMDocument3 validatenode в delphi7 не работает
Вот этот кусок
evgen29
Код: pascal
1.
2.
3.
4.
    vStrs.LoadFromFile(f);
    vStrs.Text:='<?xml version="1.0" encoding="UTF-8"?>'+vStrs.Text;
    ws:=UTF8Decode(vStrs.Text);
    vXMLDoc.loadXML(ws);

мне сильно не нравится. В чем смысл таких приседаний? Сам XML в какой кодировке сохранен?
...
Рейтинг: 0 / 0
17.03.2020, 17:51
    #39938386
evgen29
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IXMLDOMDocument3 validatenode в delphi7 не работает
в общем дело не в этом.Дело в том, что почему-то в delphi 7 эта опция работает не так.
Сделал через ole. Не ругается на validateNode(line); если я убираю цикл, т.е. методы работают нормально.
Такое впечатление, что для delphi 7 в модуле MSXML2_TLB этот метод как-то неправильно скомпилирован или не туда указывает

ps:
Сейчас ругается на несовместимость типов при самом сравнении, пытаюсь победить.
Если знаете подскажите. line по ходу содержит IDispatch и когда исчерпаны все линии выдает $00000000. Но при сравнении ругается. Пробовал и так while line<>$00000000 do и так
while line<>Unassigned do


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
function TfrmSetFormat.ValidatePrice(f: string): boolean;
var
  vXMLParserError: OleVariant;
  vXMLSchema: OleVariant;
  vXMLDoc: OleVariant;
  vStrs: TStringList;
  i, j: integer;
  str: string;
  line: Variant;
  lines: Variant;
  ws: Widestring;
begin
  result := false;
  OleInitialize(nil);
  try
    //Загрузка схемы
    vXMLSchema := CreateOleObject('MSXML2.XMLSchemaCache.6.0');
    vXMLSchema.add('', localdir + 'farmsm\' + formattypedir + '\out.xsd');
    //Загрузка документа
    vXMLDoc := CreateOleObject('MSXML2.DOMDocument.6.0');
    vXMLDoc.async := False;
    vXMLDoc.resolveExternals := false;
    vXMLDoc.validateOnParse := false;
    vXMLDoc.schemas := vXMLSchema;
    vXMLDoc.load(f);
    lines := vXMLDoc.selectNodes('//line');
    line := lines.nextNode;
    j := 0;
    i := 0;
    while line<>Unassigned do
    begin
      vXMLParserError := vXMLDoc.validateNode(line);
      //if vXMLParserError<>Null then
      //begin
      if vXMLParserError.errorCode <> 0 then
      begin
        str := Format('Ошибка при валидации <Причина: %s; Текст: %s; Код: %d>', [Trim(vXMLParserError.reason),
          vXMLParserError.srcText, vXMLParserError.errorCode]);
        vXMLDoc.removeChild(line);
        j := j + 1;
      end;
      //end;
      i := i + 1;
      line := lines.nextNode;
    end;

    if vXMLDoc.getElementsByTagName('line').length = 0 then
      ShowMessage(Format('Все строки содержат ошибки. Последняя ошибка: %s', [str]))
    else
    begin
      ShowMessage(Format('Удалено %d строк с ошибками, осталось %d строк. Последняя ошибка: %s', [j, i - j, str]));
      ShowMessage('Валидация документа прошла успешно');
      result := true;
    end;
  finally
    OleUnInitialize;
  end;
end;
...
Рейтинг: 0 / 0
17.03.2020, 18:06
    #39938393
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IXMLDOMDocument3 validatenode в delphi7 не работает
Код: pascal
1.
while (line as IDispatch) <> nil do



PS В аттаче мой рабочий MSXML
...
Рейтинг: 0 / 0
17.03.2020, 21:57
    #39938468
evgen29
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IXMLDOMDocument3 validatenode в delphi7 не работает
В общем может кому понадобится рабочий вариант по удалению строк, не проходящих проверку. Сейчас пока так, removeChild не отработал, ругается, что нет такого потомка. Но он вложенный, видимо там вложенных не находит метод. Потом при рефакторинге исправлю.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
function TfrmSetFormat.ValidatePrice(f: string): boolean;
var
  vXMLParserError: OleVariant;
  vXMLSchema: OleVariant;
  vXMLDoc: OleVariant;
  //vStrs: TStringList;
  i, j: integer;
  str: string;
  line: OleVariant;
  lines: OleVariant;
  ws, xml: Widestring;
  //d: IXMLDOMNodeList; //;
begin
  result := false;
  OleInitialize(nil);
  try
    //Загрузка схемы
    vXMLSchema := CreateOleObject('MSXML2.XMLSchemaCache.6.0');
    vXMLSchema.add('', localdir + 'farmsm\' + formattypedir + '\out.xsd');
    //Загрузка документа
    vXMLDoc := CreateOleObject('MSXML2.DOMDocument.6.0');
    vXMLDoc.async := False;
    vXMLDoc.resolveExternals := false;
    vXMLDoc.validateOnParse := false;
    vXMLDoc.schemas := vXMLSchema;
    vXMLDoc.load(f);
    lines := vXMLDoc.selectNodes('//line');
    line := lines.nextNode;
    j := 0;
    i := 0;
    while IDispatch(line) <> nil do
    begin
      vXMLParserError := vXMLDoc.validateNode(line);
      //if vXMLParserError<>Null then
      //begin
      if vXMLParserError.errorCode <> 0 then
      begin
        str := Format('Ошибка при валидации <Причина: %s; Текст: %s; Код: %s; Линия: %d>', [Trim(vXMLParserError.reason),
          vXMLParserError.srcText, vXMLParserError.errorCode, integer(i + 1)]);
        line.text := '';
        j := j + 1;
      end;
      //end;
      i := i + 1;
      line := lines.nextNode;
    end;
    xml := StringReplace(vXMLDoc.XML, '<line></line>', '', [rfReplaceAll, rfIgnoreCase]);
    if i = j then
      ShowMessage(Format('Все строки содержат ошибки. Последняя ошибка: %s', [str]))
    else
    begin
      if j > 0 then
      begin
        ShowMessage(Format('Удалено %d строк с ошибками, осталось %d строк. Последняя ошибка: %s', [j, i - j, str]));
        ShowMessage('Валидация документа прошла успешно частично.' + #13#10 + 'Ошибочные строки будут удалены при обработке автоматически.');
      end else
        ShowMessage('Валидация документа прошла полностью успешно');
      result := true;
    end;
  finally
    OleUnInitialize;
  end;
end;
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / IXMLDOMDocument3 validatenode в delphi7 не работает / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]