Skip to content

Commit 6458441

Browse files
authored
ЗаписатьТекущий пишет только текущее состояние
Merge pull request #1583 from dmpas/feature/write-current-392
2 parents 3845405 + 26c189f commit 6458441

File tree

5 files changed

+636
-5
lines changed

5 files changed

+636
-5
lines changed

src/OneScript.StandardLibrary/Xml/XmlReaderImpl.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,16 @@ private void V8CompatibleSkip()
387387

388388
[ContextMethod("Прочитать", "Read")]
389389
public bool Read()
390+
{
391+
var readingDone = ReadInternal();
392+
if (readingDone && _reader.NodeType == XmlNodeType.XmlDeclaration && _settings.IgnoreXMLDeclaration)
393+
{
394+
readingDone = ReadInternal();
395+
}
396+
return readingDone;
397+
}
398+
399+
private bool ReadInternal()
390400
{
391401
if (_reader == null)
392402
return false;
@@ -396,6 +406,15 @@ public bool Read()
396406
_emptyElemReadState = EmptyElemCompabilityState.EmptyElementRead;
397407
return true;
398408
}
409+
else if (_reader.NodeType == XmlNodeType.XmlDeclaration || _reader.NodeType == XmlNodeType.DocumentType)
410+
{
411+
var readingDone = _reader.Read();
412+
while (readingDone && _reader.NodeType == XmlNodeType.Whitespace)
413+
{
414+
readingDone = _reader.Read();
415+
}
416+
return readingDone;
417+
}
399418
else
400419
{
401420
bool readingDone = _ignoreWSChanged ? ReadWhenStateChanged() : _reader.Read();

src/OneScript.StandardLibrary/Xml/XmlReaderSettingsImpl.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ public static XmlReaderSettingsImpl Constructor(
106106
IgnoreComments = ignoreComments,
107107
IgnoreProcessingInstructions = ignoreDataProcessorInstructions,
108108
IgnoreWhitespace = ignoreSpaceCharacters,
109+
DtdProcessing = ignoreDocumentType ? DtdProcessing.Ignore : DtdProcessing.Parse,
109110
};
110111

111112
return new XmlReaderSettingsImpl(
@@ -128,6 +129,7 @@ public static XmlReaderSettingsImpl Create()
128129
IgnoreComments = true, // отличается от конструктора скрипта
129130
IgnoreProcessingInstructions = false,
130131
IgnoreWhitespace = true,
132+
DtdProcessing = DtdProcessing.Ignore,
131133
};
132134

133135
return new XmlReaderSettingsImpl("1.0", context, settings);

src/OneScript.StandardLibrary/Xml/XmlWriterImpl.cs

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,110 @@ public void WriteText(string text)
183183
[ContextMethod("ЗаписатьТекущий","WriteCurrent")]
184184
public void WriteCurrent(XmlReaderImpl reader)
185185
{
186-
_writer.WriteNode(reader.GetNativeReader(), false);
186+
var nodeType = reader.NodeType.UnderlyingValue;
187+
switch (nodeType)
188+
{
189+
case XmlNodeType.Element:
190+
CopyElementAndAttributes(reader, this);
191+
break;
192+
case XmlNodeType.XmlDeclaration:
193+
WriteXMLDeclaration();
194+
break;
195+
case XmlNodeType.DocumentType:
196+
CopyDocumentType(reader, this);
197+
break;
198+
case XmlNodeType.Attribute:
199+
CopyAttribute(reader.Name, reader.Value, reader, this);
200+
break;
201+
case XmlNodeType.EndElement:
202+
WriteEndElement();
203+
break;
204+
case XmlNodeType.CDATA:
205+
WriteCDATASection(reader.Value);
206+
break;
207+
case XmlNodeType.Text:
208+
WriteText(reader.Value);
209+
break;
210+
case XmlNodeType.Whitespace:
211+
case XmlNodeType.SignificantWhitespace:
212+
WriteText(reader.Value);
213+
break;
214+
case XmlNodeType.Comment:
215+
WriteComment(reader.Value);
216+
break;
217+
case XmlNodeType.EntityReference:
218+
WriteEntityReference(reader.Name);
219+
break;
220+
case XmlNodeType.ProcessingInstruction:
221+
WriteProcessingInstruction(reader.Name, reader.Value);
222+
break;
223+
case XmlNodeType.Entity:
224+
case XmlNodeType.EndEntity:
225+
case XmlNodeType.Document:
226+
case XmlNodeType.DocumentFragment:
227+
case XmlNodeType.Notation:
228+
throw new RuntimeException(new Localization.BilingualString($"Копирование узла {nodeType} не поддерживается"));
229+
default:
230+
break;
231+
}
232+
}
233+
234+
private static void CopyDocumentType(XmlReaderImpl reader, XmlWriterImpl writer)
235+
{
236+
writer.WriteDocumentType(reader.Name, reader.Value);
237+
}
238+
239+
private static void CopyElementAndAttributes(XmlReaderImpl reader, XmlWriterImpl writer)
240+
{
241+
writer.WriteStartElement(reader.Name);
242+
var attributeCount = reader.AttributeCount();
243+
if (attributeCount != 0)
244+
{
245+
for (var attributeIndex = 0; attributeIndex < attributeCount; attributeIndex++)
246+
{
247+
var attributeName = reader.AttributeName(attributeIndex);
248+
var attributeValue = reader.GetAttribute(ValueFactory.Create(attributeIndex)).ExplicitString();
249+
CopyAttribute(attributeName, attributeValue, reader, writer);
250+
}
251+
}
252+
}
253+
254+
private static void CopyAttribute(string attributeNameIn, string attributeValue, XmlReaderImpl reader, XmlWriterImpl writer)
255+
{
256+
var splittedName = splitName(attributeNameIn);
257+
if (!string.IsNullOrEmpty(splittedName.prefix))
258+
{
259+
var readerNsContext = (XmlNamespaceContext)reader.NamespaceContext;
260+
var writerNsContext = (XmlNamespaceContext)writer.NamespaceContext;
261+
if (splittedName.prefix.Equals("xmlns", StringComparison.Ordinal))
262+
{
263+
writer.WriteNamespaceMapping(splittedName.localName, attributeValue);
264+
return;
265+
}
266+
else
267+
{
268+
var uri = readerNsContext.LookupNamespaceUri(splittedName.prefix);
269+
if (uri is BslStringValue)
270+
{
271+
var value = uri.ExplicitString();
272+
var currentPrefix = writerNsContext.LookupPrefix(value);
273+
if (!(currentPrefix is BslStringValue && currentPrefix.ExplicitString().Equals(splittedName.prefix, StringComparison.Ordinal)))
274+
{
275+
writer.WriteNamespaceMapping(splittedName.prefix, value);
276+
}
277+
splittedName.prefix = value;
278+
}
279+
}
280+
}
281+
writer.WriteAttribute(splittedName.localName, splittedName.prefix, attributeValue);
282+
}
283+
284+
private static (string prefix, string localName) splitName(string nameOrLocalName)
285+
{
286+
var parts = nameOrLocalName.Split(':');
287+
if (parts.Length > 1) return (parts[0], parts[1]);
288+
if (parts[0].Equals("xmlns", StringComparison.Ordinal)) return (parts[0], "");
289+
return ("", parts[0]);
187290
}
188291

189292
[ContextMethod("ЗаписатьТипДокумента","WriteDocumentType")]

tests/testrunner.os

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,18 @@
8282
КонецЕсли;
8383
КонецПроцедуры
8484

85+
Процедура ПроверитьРавенствоСтрокБезУчетаРегистра(ПервоеЗначение, ВтороеЗначение, ДопСообщениеОшибки = "") Экспорт
86+
Если нрег(ПервоеЗначение) <> нрег(ВтороеЗначение) Тогда
87+
Если ТипЗнч(ПервоеЗначение) = Тип("Строка") и ТипЗнч(ВтороеЗначение) = Тип("Строка") Тогда
88+
ВызватьИсключение ИсключениеНеравенстваСтрок(ПервоеЗначение, ВтороеЗначение, Истина) + "
89+
|" + ДопСообщениеОшибки;
90+
КонецЕсли;
91+
92+
СообщениеОшибки = "Сравниваемые значения ("+ПервоеЗначение+"; "+ВтороеЗначение+") не равны, а хотели, чтобы были равны." + ФорматДСО(ДопСообщениеОшибки);
93+
ВызватьИсключение(СообщениеОшибки);
94+
КонецЕсли;
95+
КонецПроцедуры
96+
8597
Процедура ПроверитьНеРавенство(ПервоеЗначение, ВтороеЗначение, ДопСообщениеОшибки = "") Экспорт
8698
Если ПервоеЗначение = ВтороеЗначение Тогда
8799
СообщениеОшибки = "Сравниваемые значения ("+ПервоеЗначение+"; "+ВтороеЗначение+") равны, а хотели, чтобы были не равны." + ФорматДСО(ДопСообщениеОшибки);
@@ -196,20 +208,28 @@
196208
Возврат СтрЗаменить(СтрЗаменить(Строка, Символы.ПС, "\n"), Символы.ВК, "\r");
197209
КонецФункции
198210

199-
Функция ИсключениеНеравенстваСтрок(ПервоеЗначение, ВтороеЗначение)
200-
ДиапазонОтНачала = 5;
201-
ДиапазонВКонце = 5;
202-
СтрокаНабора = " "; // длина = 2*ДиапазонОтНачала
211+
Функция ИсключениеНеравенстваСтрок(ПервоеЗначение, ВтороеЗначение, Знач БезУчетаРегистра = Ложь)
212+
ДиапазонОтНачала = 17;
213+
ДиапазонВКонце = 17;
214+
СтрокаНабора = СтрСоединить(Новый Массив(2*ДиапазонОтНачала), " ");
203215

204216
МинДлина = Мин(СтрДлина(ПервоеЗначение), СтрДлина(ВтороеЗначение));
205217
ИндексРазличия = МинДлина + 1;
206218
Для Сч = 1 По МинДлина Цикл
219+
207220
Символ1 = Сред(ПервоеЗначение, Сч, 1);
208221
Символ2 = Сред(ВтороеЗначение, Сч, 1);
222+
223+
Если БезУчетаРегистра Тогда
224+
Символ1 = нрег(Символ1);
225+
Символ2 = нрег(Символ2);
226+
КонецЕсли;
227+
209228
Если Символ1 <> Символ2 Тогда
210229
ИндексРазличия = Сч;
211230
Прервать;
212231
КонецЕсли;
232+
213233
КонецЦикла;
214234

215235
ОтступНачала = ИндексРазличия - ДиапазонОтНачала;

0 commit comments

Comments
 (0)