powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / ParseStream
21 сообщений из 21, страница 1 из 1
ParseStream
    #37323638
AndreiG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!
Уважаемое сообщество подскажите пожалуйста.
Есть поток в котором храниться xml (кусок xml ниже)
<ID.33>
<ID.33.1.TypeMessage>APA</ID.33.1.TypeMessage>
</ID.33>
<PID>
<PID.5.FIO>
<PN.1.Surname>hjkhjkfhsdjkf</PN.1.Surname>
<PN.2.Name>hfghdfh</PN.2.Name>
<PN.3.Patronymic>hfghfghdf</PN.3.Patronymic>
<PID.7.BirthDay><TS>62251</TS></PID.7.BirthDay>
Как распарсить данный поток и получить значение "hjkhjkfhsdjkf" из элемента <PN.1.Surname>?
...
Рейтинг: 0 / 0
ParseStream
    #37323694
Блок А.Н.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Создаете класс, наследованный от %XML.Adaptor, настраиваете поля (по умолчанию они будут отображаться с тегами как названия полей)

потом создаете объект класса %XML.Reader, открываете поток, и

d reader.Correlate("PID","MyClass")
d reader.Next(.reply,.sc)

У вас двухуровневая структура как минимум, и класс должен быть содержащим подклассы.
Как такие классы оформлять - посмотрите в тебе XML-Word, там обратная задача, из классов сгенерить нужный XML,
но разницы особой нет.

Еще можно через %XML.TextReader, но это гораздо сложнее, чем через отображение классов.
...
Рейтинг: 0 / 0
ParseStream
    #37323707
AndreiG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте!
Я этот поток передаю с клиента на сервер! Мне нужно распарсить и получить фамилию, потом эту фамилию использовать при запросе!
...
Рейтинг: 0 / 0
ParseStream
    #37323723
andrew_tsw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно сделать и без использования reader.Correlate("PID","MyClass")
Например, так:

set reader = ##class(%XML.Reader).%New()
do reader.OpenStream(stream)
#dim document as %XML.Document = reader.Document
#dim node as %XML.Node = document.GetDocumentElement()
и т.д.

а дальше последовательно просматривать структуру документа и искать то место, которое нужно.

Representing an XML Document as a DOM
...
Рейтинг: 0 / 0
ParseStream
    #37323926
AndreiG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а как получить значение эл-та <PN.2.Name>, если он в эл-те <PID.5.FIO>?
<PID.5.FIO>
<PN.1.Surname>hjkhjkfhsdjkf</PN.1.Surname>
<PN.2.Name>hfghdfh</PN.2.Name>
</PID.5.FIO>
...
Рейтинг: 0 / 0
ParseStream
    #37323999
Блок А.Н.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вы каким методом хотите?
Что уже попробовали сделать?
...
Рейтинг: 0 / 0
ParseStream
    #37324013
AndreiG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
т.к. я на сервере делаю парсинг я пробую как предложил andrew_tsw. не получается взять значение элемента по названию тега
...
Рейтинг: 0 / 0
ParseStream
    #37324029
Блок А.Н.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А его методом не по названию, а по порядку, если не ошибаюсь.
Причем там причуды в некоторых местах, так как элементом являются не только элементы, но и аттрибуты, контент и всякое такое.
Еще разбирать придется, в каком же месте и что мы прочитали.

Прямо рекомендую свой способ.
Может быть, он в первый раз кажется сложнее, но это тот случай, когда "лучше день потерять, потом за 5 минут долететь".
Получаете сразу готовые объекты классов с нужными полями.
...
Рейтинг: 0 / 0
ParseStream
    #37324040
Turk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AndreiG,
примерный код с помощью %XML.TextReader (без необходимости заведения дополнительных классов):
Код: plaintext
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.
s sc = ##class(%XML.TextReader).ParseFile(FileName,.reader)
q:($$$ISERR(sc)) $lb(0, "Ошибка разбора XML-файла: "_$SYSTEM.Status.GetErrorText(sc))
//
s res = $lb(0, "Элемент PN.3.Patronymic не найден")
s fExit = 0
while (reader.Read())
{
	continue:(reader.NodeType'="element")
	//
	if (reader.Name = "PID.5.FIO")
	{
		while (reader.Read())
		{
			q:(reader.Name="PID.5.FIO")&&(reader.NodeType="endelement")
			//
			if (reader.Name = "PN.3.Patronymic") && (reader.NodeType = "element")
			{
				s res = $lb(1,reader.Value)
				s fExit = 1
				q
			}
		}
		q:(fExit)
	}
}
//
k reader
q res
...
Рейтинг: 0 / 0
ParseStream
    #37324043
AndreiG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
спс за подсказку! буду пробовать.
...
Рейтинг: 0 / 0
ParseStream
    #37324104
AndreiG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Turk, попробовал ваш пример. Результат получаю вот такой:
Мне такое не надо)
...
Рейтинг: 0 / 0
ParseStream
    #37324119
Блок А.Н.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Метод Turk-работает, вы че-то наверно не так сделали.

Кстати, у вас в примере XML корявый, PID не закрывается
...
Рейтинг: 0 / 0
ParseStream
    #37324140
AndreiG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вот весь xml
<?xml version="1.0" encoding="Windows-1251"?>
<InfoPatient>
<MSH>
<MSH.1.FieldSeparator>|</MSH.1.FieldSeparator>
<MSH.2.EncodingCharacters>^~\</MSH.2.EncodingCharacters>
<MSH.3.SendingApplication>
<MSH.3.1.SendingApplicationName>HEALTHWEBPATIENT</MSH.3.1.SendingApplicationName>
<MSH.3.2.SendingNamespace>HEALTH</MSH.3.2.SendingNamespace>
</MSH.3.SendingApplication>
<MSH.4.SendingFacility>HOSPITAL</MSH.4.SendingFacility>
<MSH.5.HostApplication>
<MSH.5.1.HostApplicationName>MIS .... </MSH.5.1.HostApplicationName>
<MSH.5.2.HostNamespace>HEALTH</MSH.5.2.HostNamespace>
</MSH.5.HostApplication>
<MSH.6.HostFacility>HOSPITAL 123</MSH.6.HostFacility>
<MSH.7.DatatimeOfMessage>
<TS>
<TS.1>201108241326</TS.1>
</TS>
</MSH.7.DatatimeOfMessage>
</MSH>
<QRT>
<ST.25>201108241326</ST.25>
<ID.26>R</ID.26>
<CQ.31>RD</CQ.31>
<ID.33>
<ID.33.1.TypeMessage>APA</ID.33.1.TypeMessage>
</ID.33>
<PID>
<PID.5.FIO>
<PN.1.Surname>hjkhjkfhsdjkf</PN.1.Surname>
<PN.2.Name>hfghdfh</PN.2.Name>
<PN.3.Patronymic>hfghfghdf</PN.3.Patronymic>
<PID.7.BirthDay>
<TS>62251</TS>
</PID.7.BirthDay>
</PID.5.FIO>
<PID.11.Adress>
<AD.1/>
<AD.2/>
<AD.3/>
</PID.11.Adress>
</PID>
</QRT>
</InfoPatient>

а вот метод:
Method GetFile(ByRef pStream As %Library.BinaryStream) [ WebMethod ]
{

s sc = ##class(%XML.TextReader).ParseStream(pStream,.reader)

q:($$$ISERR(sc)) $lb(0, "Ошибка разбора XML-файла: "_$SYSTEM.Status.GetErrorText(sc))
//
s res = $lb(0, "Элемент PN.3.Patronymic не найден")

s fExit = 0

while (reader.Read())

{
continue:(reader.NodeType'="element")
//

if (reader.Name = "PID.5.FIO")
{
while (reader.Read())
{

q:(reader.Name="PID.5.FIO")&&(reader.NodeType="endelement")
//

if (reader.Name = "PN.1.Surname") && (reader.NodeType = "element")
{
s res = $lb(1,reader.Value)


Set file=##class(%Library.File).%New("C:\2.txt")
Set ok=file.Open("WN")
If 'ok Quit
Do file.Write(res)
Do file.Close()


s fExit = 1

q
}
}
q:(fExit)
}
}
//

k reader
q res


}
}
...
Рейтинг: 0 / 0
ParseStream
    #37324141
AndreiG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
что не так?
...
Рейтинг: 0 / 0
ParseStream
    #37324162
Блок А.Н.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так лучше.
Секунду, нарисую пример.

Вам же по идее нужно парсить весь файл?
Вы же не радо одного поля это затеваете?
...
Рейтинг: 0 / 0
ParseStream
    #37324172
AndreiG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мне надо из потока pStream, который приходит от WebClient и содержит различную информацию о человеке вытащить Фамилию и использовать ее в запросе
...
Рейтинг: 0 / 0
ParseStream
    #37324201
Блок А.Н.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хм, в моем методе бяка в том, что если мы цепляем из потока тег PID, то мы должны для него полное отображение классов нарисовать, а это бывает много.
Я решил поискать и распарсить PID, для того, чтобы распарсить InfoPatient классов надо наплодить больше.

Собственно, сам код:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
 s reader=##class(%XML.Reader).%New()
 d reader.OpenFile("e:\temp\1.xml")
 d reader.Correlate("PID","Reader.PID") 
 #dim obj as Reader.PID
 while reader.Next(.obj,.sc)
 	{w !,obj.FIO.Surname
 	}
 

Нужные классы:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Class Reader.PID Extends (%Persistent, %XML.Adaptor)
{

Property FIO As FIO(XMLNAME = "PID.5.FIO");

Property Address As Address(XMLNAME = "PID.11.Adress");

}
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Class Reader.FIO Extends (%Persistent, %XML.Adaptor)
{

Property Surname As %String(XMLNAME = "PN.1.Surname");

Property Name As %String(XMLNAME = "PN.2.Name");

Property Patronymic As %String(XMLNAME = "PN.3.Patronymic");

Property Birtday As BirthDay(XMLNAME = "PID.7.BirthDay");

}
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Class Reader.Address Extends (%Persistent, %XML.Adaptor)
{

Property AD1 As Value(XMLNAME = "AD.1");

Property AD2 As Value(XMLNAME = "AD.2");

Property AD3 As Value(XMLNAME = "AD.3");

}
Код: plaintext
1.
2.
3.
4.
5.
6.
Class Reader.Value Extends (%Persistent, %XML.Adaptor)
{

Property Value As %String(XMLPROJECTION = "CONTENT");

}
...
Рейтинг: 0 / 0
ParseStream
    #37324536
Блок А.Н.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Че-то чую, не все классы выложил :)
Код: plaintext
1.
2.
3.
4.
5.
Class Reader.BirthDay Extends (%Persistent, %XML.Adaptor)
{

Property TS As Reader.Value(XMLNAME = "TS");

}
...
Рейтинг: 0 / 0
ParseStream
    #37324617
AndreiG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо всем за подсказки! Проблему решили так:
Method GetFile(ByRef pStream As %Library.BinaryStream) [ WebMethod ]
{
Set cls=##CLASS(%XML.TextReader).ParseStream(pStream,.reader)
Set stream=##class(%GlobalCharacterStream).%New()
k ^testXML
While reader.Read()
{
If (reader.NodeType = "element")
{
s nam=reader.Name
if (nam="PN.1.Surname")||( nam="PN.2.Name")||(nam="PN.3.Patronymic")
{
while reader.Read()
{
q:(reader.Name=nam)&&(reader.NodeType="endelement")
s val=reader.Value
s testXML(nam)=val

q
}
}

}

}

s ^testXML("FIO")=testXML("PN.1.Surname")_testXML("PN.2.Name")_testXML("PN.3.Patronymic")


}
...
Рейтинг: 0 / 0
ParseStream
    #37325458
Turk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AndreiGTurk, попробовал ваш пример. Результат получаю вот такой:
Мне такое не надо)
В моем примере возвращается не строка, а список ($listbuild), где 1й элемент - результат операции (0 - ошибка, 1 - успешно), а 2й - строка со значением тэга (если успешно) или текст ошибки.
...
Рейтинг: 0 / 0
ParseStream
    #37325509
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndreiGвот весь xml
Код: plaintext
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.
<?xml version="1.0" encoding="Windows-1251"?>
<InfoPatient>
  <MSH>
    <MSH. 1 .FieldSeparator>|</MSH. 1 .FieldSeparator>
    <MSH. 2 .EncodingCharacters>^~\</MSH. 2 .EncodingCharacters>
    <MSH. 3 .SendingApplication>
      <MSH. 3 . 1 .SendingApplicationName>HEALTHWEBPATIENT</MSH. 3 . 1 .SendingApplicationName>
      <MSH. 3 . 2 .SendingNamespace>HEALTH</MSH. 3 . 2 .SendingNamespace>
    </MSH. 3 .SendingApplication>
    <MSH. 4 .SendingFacility>HOSPITAL</MSH. 4 .SendingFacility>
    <MSH. 5 .HostApplication>
      <MSH. 5 . 1 .HostApplicationName>MIS .... </MSH. 5 . 1 .HostApplicationName>
      <MSH. 5 . 2 .HostNamespace>HEALTH</MSH. 5 . 2 .HostNamespace>
    </MSH. 5 .HostApplication>
    <MSH. 6 .HostFacility>HOSPITAL  123 </MSH. 6 .HostFacility>
    <MSH. 7 .DatatimeOfMessage>
      <TS>
        <TS. 1 > 201108241326 </TS. 1 >
      </TS>
    </MSH. 7 .DatatimeOfMessage>
  </MSH>
  <QRT>
    <ST. 25 > 201108241326 </ST. 25 >
    <ID. 26 >R</ID. 26 >
    <CQ. 31 >RD</CQ. 31 >
    <ID. 33 >
      <ID. 33 . 1 .TypeMessage>APA</ID. 33 . 1 .TypeMessage>
    </ID. 33 >
    <PID>
      <PID. 5 .FIO>
        <PN. 1 .Surname>hjkhjkfhsdjkf</PN. 1 .Surname>
        <PN. 2 .Name>hfghdfh</PN. 2 .Name>
        <PN. 3 .Patronymic>hfghfghdf</PN. 3 .Patronymic>
        <PID. 7 .BirthDay>
          <TS> 62251 </TS>
        </PID. 7 .BirthDay>
      </PID. 5 .FIO>
      <PID. 11 .Adress>
        <AD. 1 />
        <AD. 2 />
        <AD. 3 />
      </PID. 11 .Adress>
    </PID>
  </QRT>
</InfoPatient>

Если это и весь текст - загнать его в строчку, а далее

Код: plaintext
w $p($p(str,"<PN.1.Surname>", 2 ),"</PN.1.Surname>")
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / ParseStream
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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