Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Технологии
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 11.09.2017, 08:49
BarakudaX777 BarakudaX777 вне форума
Прохожий
 
Регистрация: 16.02.2013
Сообщения: 13
Репутация: 10
По умолчанию Помогите понять как обработать XML с префиксами

Добрый день знатокам!
Написал программу которая обрабатывает XML документы и загружает данные файла в программу (ГИС "Ингео"). Строю объект по координатам с данного файла и переношу семантику.
Программа работает, данные переносятся, но возникла проблема что в файлах XML которые скачивает пользователь почему то меняются префиксы (или как они точнее называются). Пример:

Код:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="https://portal.rosreestr.ru/xsl/EGRP/Reestr_Extract_Gkn/ZU/07/Common.xsl"?>
<KPZU xmlns="urn://x-artefacts-rosreestr-ru/outgoing/kpzu/6.0.1" xmlns:smev="urn://x-artefacts-smev-gov-ru/supplementary/commons/1.0.1" 
xmlns:num="urn://x-artefacts-rosreestr-ru/commons/complex-types/numbers/1.0" xmlns:adrs="urn://x-artefacts-rosreestr-ru/commons/complex-types/address-output/4.0.1" 
xmlns:spa="urn://x-artefacts-rosreestr-ru/commons/complex-types/entity-spatial/5.0.1" 
xmlns:cer="urn://x-artefacts-rosreestr-ru/commons/complex-types/certification-doc/1.0" 
xmlns:doc="urn://x-artefacts-rosreestr-ru/commons/complex-types/document-output/4.0.1" 
xmlns:nobj="urn://x-artefacts-rosreestr-ru/commons/complex-types/natural-objects-output/1.0.1">
    <Parcel CadastralNumber="56:43:0110026:24" State="06" DateCreated="2008-03-19" Method="4">
         <EntitySpatial EntSys="ID0">
            <spa:SpatialElement>
                <spa:SpelementUnit TypeUnit="Точка" SuNmb="1">
                    <spa:Ordinate X="372630.97" Y="3329297.42" OrdNmb="1" DeltaGeopoint="0.1" />
                </spa:SpelementUnit>
                <spa:SpelementUnit TypeUnit="Точка" SuNmb="2">
                    <spa:Ordinate X="372649.52" Y="3329313.77" OrdNmb="1" DeltaGeopoint="0.1" />
                </spa:SpelementUnit>
                <spa:SpelementUnit TypeUnit="Точка" SuNmb="3">
                    <spa:Ordinate X="372673.14" Y="3329286.6" OrdNmb="1" DeltaGeopoint="0.1" />
                </spa:SpelementUnit>
                <spa:SpelementUnit TypeUnit="Точка" SuNmb="4">
                    <spa:Ordinate X="372654.37" Y="3329270.19" OrdNmb="1" DeltaGeopoint="0.1" GeopointZacrep="626002000000" />
                </spa:SpelementUnit>
                <spa:SpelementUnit TypeUnit="Точка" SuNmb="5">
                    <spa:Ordinate X="372631.37" Y="3329296.97" OrdNmb="1" DeltaGeopoint="0.3" GeopointZacrep="626002000000" />
                </spa:SpelementUnit>
                <spa:SpelementUnit TypeUnit="Точка" SuNmb="1">
                    <spa:Ordinate X="372630.97" Y="3329297.42" OrdNmb="1" DeltaGeopoint="0.1" />
                </spa:SpelementUnit>
            </spa:SpatialElement>
        </EntitySpatial>
</Parcel>
</KPZU>

Пример 2:

Код:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="https://portal.rosreestr.ru/xsl/GKN/Vidimus/07/common.xsl"?>
<KVZU
	xmlns:ns2="urn://x-artefacts-rosreestr-ru/commons/complex-types/numbers/1.0"
	xmlns:ns3="urn://x-artefacts-rosreestr-ru/commons/complex-types/entity-spatial/5.0.1"
	xmlns:adrOut4="urn://x-artefacts-rosreestr-ru/commons/complex-types/address-output/4.0.1"
	xmlns:ns5="urn://x-artefacts-rosreestr-ru/commons/complex-types/natural-objects-output/1.0.1"
	xmlns:ns6="urn://x-artefacts-smev-gov-ru/supplementary/commons/1.0.1"
	xmlns:ns7="urn://x-artefacts-rosreestr-ru/commons/complex-types/document-output/4.0.1"
	xmlns:ns8="urn://x-artefacts-rosreestr-ru/commons/complex-types/certification-doc/1.0"
	xmlns="urn://x-artefacts-rosreestr-ru/outgoing/kvzu/7.0.1">
	<Parcel CadastralNumber="56:18:0601002:361" State="06" DateCreated="2012-12-17">
               <EntitySpatial EntSys="ID1">
						<ns3:SpatialElement>
							<ns3:SpelementUnit TypeUnit="Точка" SuNmb="5">
								<ns3:Ordinate X="385907.66" Y="3364855.93" OrdNmb="1" />
							</ns3:SpelementUnit>
							<ns3:SpelementUnit TypeUnit="Точка" SuNmb="2">
								<ns3:Ordinate X="385906.23" Y="3364855.79" OrdNmb="1" DeltaGeopoint="0.20" />
							</ns3:SpelementUnit>
							<ns3:SpelementUnit TypeUnit="Точка" SuNmb="3">
								<ns3:Ordinate X="385903.48" Y="3364883.70" OrdNmb="1" DeltaGeopoint="0.20" />
							</ns3:SpelementUnit>
							<ns3:SpelementUnit TypeUnit="Точка" SuNmb="6">
								<ns3:Ordinate X="385904.92" Y="3364883.84" OrdNmb="1" />
							</ns3:SpelementUnit>
							<ns3:SpelementUnit TypeUnit="Точка" SuNmb="5">
								<ns3:Ordinate X="385907.66" Y="3364855.93" OrdNmb="1" />
							</ns3:SpelementUnit>
						</ns3:SpatialElement>
						<ns3:Borders>
							<ns3:Border Spatial="1" Point1="5" Point2="2">
								<ns3:Edge>
									<ns3:Length>1.44</ns3:Length>
									<ns3:DirectionAngle>
										<ns3:Degree>185</ns3:Degree>
										<ns3:Minute>35</ns3:Minute>
									</ns3:DirectionAngle>
								</ns3:Edge>
							</ns3:Border>
							<ns3:Border Spatial="1" Point1="2" Point2="3">
								<ns3:Edge>
									<ns3:Length>28.05</ns3:Length>
									<ns3:DirectionAngle>
										<ns3:Degree>95</ns3:Degree>
										<ns3:Minute>38</ns3:Minute>
									</ns3:DirectionAngle>
								</ns3:Edge>
							</ns3:Border>
							<ns3:Border Spatial="1" Point1="3" Point2="6">
								<ns3:Edge>
									<ns3:Length>1.45</ns3:Length>
									<ns3:DirectionAngle>
										<ns3:Degree>5</ns3:Degree>
										<ns3:Minute>33</ns3:Minute>
									</ns3:DirectionAngle>
								</ns3:Edge>
							</ns3:Border>
							<ns3:Border Spatial="1" Point1="6" Point2="5">
								<ns3:Edge>
									<ns3:Length>28.04</ns3:Length>
									<ns3:DirectionAngle>
										<ns3:Degree>275</ns3:Degree>
										<ns3:Minute>36</ns3:Minute>
									</ns3:DirectionAngle>
								</ns3:Edge>
							</ns3:Border>
						</ns3:Borders>
					</EntitySpatial>
</Parcel>
</KPZU>

В первом случае префикс "spa:", в другом уже "ns3". Может как то можно игнорировать данный префикс и как это сделать?

Для поиска дочерних элементов использую функцию
Код:
function TXMLParserForm.GetNodeByPath(Root: IXMLNode; Path,Namespace: string): IXMLNode;
var tempNode:IXMLNode;
  currentElement:string;
  delimPos:integer;
begin
  tempNode:=nil;
  if Root=nil then begin result:=nil;exit;end;
  if Path<>'' then begin
      delimPos := pos('\',Path);
      tempNode:=Root;
      while delimPos>0 do begin    //Усли имеется несколько элементов
          currentElement := Copy(Path,1,delimPos-1);
          Path := Copy(Path,delimPos+1,length(Path)-delimPos);
          if currentElement='..' then begin
            tempNode:=tempNode.ParentNode;
          end else begin
            tempNode:=tempNode.ChildNodes.FindNode(currentElement,Namespace);
          end;
          if tempNode=nil then begin result:=nil;exit;end;
          delimPos := pos('\',Path);
      end;
      if (delimPos=0) then begin
        if Path='..' then tempNode:=tempNode.ParentNode else tempNode := tempNode.ChildNodes.FindNode(Path,Namespace);
        if tempNode=nil then begin result:=nil;exit;end;
        result := tempNode;
        exit;
      end;
  end;
end;

Вызываю следующим способом:
Код:
currNode := GetNodeByPath(RootNode,Root+'\'+Path,'');
Где передается корневой элемент и путь вида "Ветка1\Ветка2\Ветка.."
В конкретном случае
Код:
currNode := GetNodeByPath(RootNode,Root+'EntitySpatial\spa:SpatialElement','');

Последний раз редактировалось BarakudaX777, 11.09.2017 в 14:33.
Ответить с цитированием
  #2  
Старый 11.09.2017, 14:04
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

А какую инфу вы выдираете - координаты Х/У плюс дельта?
Можно ведь и "ручками" это делать, без прокладок типа IXMLParser,
чисто по тегам
Ответить с цитированием
  #3  
Старый 11.09.2017, 14:24
BarakudaX777 BarakudaX777 вне форума
Прохожий
 
Регистрация: 16.02.2013
Сообщения: 13
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
А какую инфу вы выдираете - координаты Х/У плюс дельта?
Можно ведь и "ручками" это делать, без прокладок типа IXMLParser,
чисто по тегам
Это чисто пример проблемного элемента! сам XML Документ достаточно огромный. Представляет собой выписку по земельному участку, в которой есть информация об объектах, правообладателях, видах собственности, кадастровых номерах, зонах и так далее.
Программа делается в помощь муниципальному образованию обрабатывать схемы росреестра. Проблема таится в том что иногда файлы xml документов имеют разный префикс (или именное пространство). Не знаю зачем это так сделано. Но это приводит к трудностям. Программа работает работает работает а потом раз поменялись на ns7 или pt1 и тому подобно. Из за того что я в программе указываю ветку с указанием префикса, а namespace ставлю пустым, при смене префикса ветки уже не будет. следовательно ничего не выполнится с этой веткой
Ответить с цитированием
  #4  
Старый 11.09.2017, 14:32
BarakudaX777 BarakudaX777 вне форума
Прохожий
 
Регистрация: 16.02.2013
Сообщения: 13
Репутация: 10
По умолчанию

Программа позволяет импортировать данные в ГИС «ИНГЕО» из XML файлов. Так как структура XML файлов различна и со временем изменяется, было решено разрабатывать схему обработчика XML документа. Данная схема так же пишется на XML и представляет собой последовательность действий, которых программа должна предпринять, для обработки XML файла.
Используя данный подход к обработке XML Документов становится возможно разрабатывать схемы обработки новых документов не внося изменения в логику самой программы.

Но с учетом прописывания веток с префиксом, в некоторых случаях приходится править схему

Прикреплю описание как я сделал схему и что она умеет.
Описание схем обработки XML документов

Последний раз редактировалось BarakudaX777, 11.09.2017 в 14:34.
Ответить с цитированием
  #5  
Старый 11.09.2017, 15:26
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Тогда здесь само напрашивается применение сравнения if then или, если заковыристых тегов много, то case, и если "префикс" отличается от стандарта, то обрабатывать это место следует с другими параметрами поиска указателей, другими словами, похоже "гибкости" нужно добавить, чтоб правильно всё фунциклило
Ответить с цитированием
  #6  
Старый 11.09.2017, 17:25
BarakudaX777 BarakudaX777 вне форума
Прохожий
 
Регистрация: 16.02.2013
Сообщения: 13
Репутация: 10
По умолчанию

Условия не использовать то что префиксы меняются, какие становятся никто не узнает пока не скачает XML. Не предугадаешь что за префиксы сегодня а что будут потом. я все же смотрю в сторону того чтобы просто их игнорировать, убирая той части что за двоеточием, просто отбрасывая ее. Вот только думал может есть какой то способ это сделать на уровне API а не изобретать велосипед.
По сути эти префиксы не нужны мне и их можно просто удалять.
Ответить с цитированием
  #7  
Старый 11.09.2017, 18:24
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Цитата:
Сообщение от BarakudaX777
...я все же смотрю в сторону того чтобы просто их игнорировать, убирая той части что за двоеточием, просто отбрасывая ее...
Наверное, нужно до двоеточия, и ещё закрывающий тег убрать, вот как это можно реализовать
Код:
Delete(s,1,Pos(':',s));
Delete(s,Length(s)-2,3);

З.Ы. А ведь можно ещё после получения "абзаца"
с изменёнными префиксами заменить их на свои,
константные перед последующей обработкой,
это чтоб логику сильно не ломать работающей
части приведённой функции

Последний раз редактировалось Alegun, 11.09.2017 в 18:48.
Ответить с цитированием
  #8  
Старый 11.09.2017, 23:57
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,053
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Вообще, тут SAX парсер просится. Тогда при появлении тега у тебя в код "сваливается" его имя. Вот и анализируешь его, опуская схему. В принципе, можно и так написать, на DOM парсере. Только придется честно в цикле перебирать все ноды, т.е. отказаться от функции FindNode или написать свою, которая учитывает это безобразие.

ЗЫ. Кстати, возможные префиксы можно получить из атрибутов корневого тега, там они перечислены при описании соотв схем.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 00:00.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter