powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / IXMLDOMDocument3 validatenode в delphi7 не работает
7 сообщений из 7, страница 1 из 1
IXMLDOMDocument3 validatenode в delphi7 не работает
    #39938213
evgen29
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте! Валидировал свой 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
IXMLDOMDocument3 validatenode в delphi7 не работает
    #39938273
goldmi45
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
evgen29,

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

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


так validate проходит нормально, даже если я не убираю ошибки. vXMLParserError.errorCode просто не 0 становится и есть описание ошибки.
Попробовал на документе, где нет ошибок. Validate проходит, validatenode опять тоже самое. Не в этом дело.
...
Рейтинг: 0 / 0
IXMLDOMDocument3 validatenode в delphi7 не работает
    #39938371
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот этот кусок
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
IXMLDOMDocument3 validatenode в delphi7 не работает
    #39938386
evgen29
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
в общем дело не в этом.Дело в том, что почему-то в 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
IXMLDOMDocument3 validatenode в delphi7 не работает
    #39938393
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
while (line as IDispatch) <> nil do



PS В аттаче мой рабочий MSXML
...
Рейтинг: 0 / 0
IXMLDOMDocument3 validatenode в delphi7 не работает
    #39938468
evgen29
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В общем может кому понадобится рабочий вариант по удалению строк, не проходящих проверку. Сейчас пока так, 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
7 сообщений из 7, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / IXMLDOMDocument3 validatenode в delphi7 не работает
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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