From 48f75cdb8cdcbe0f8efc47961c437e92233b643b Mon Sep 17 00:00:00 2001 From: Mr-Rm Date: Mon, 29 Jun 2026 15:38:31 +0400 Subject: [PATCH 1/2] =?UTF-8?q?fix=20#1705:=20=D0=BF=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D0=BA=D0=B0=20=D0=BF=D1=80=D0=B8=D0=B5=D0=BC=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=B0=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85;=20?= =?UTF-8?q?=D0=B2=D0=BE=D0=B7=D0=B2=D1=80=D0=B0=D1=82=20=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=BA=D0=B8=20=D0=B8=D0=B7=20=D0=97=D0=B0=D0=BA=D1=80?= =?UTF-8?q?=D1=8B=D1=82=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Xml/XmlWriterImpl.cs | 76 +++++++++++++------ tests/xmlwrite.os | 21 +++++ 2 files changed, 75 insertions(+), 22 deletions(-) diff --git a/src/OneScript.StandardLibrary/Xml/XmlWriterImpl.cs b/src/OneScript.StandardLibrary/Xml/XmlWriterImpl.cs index 466cd7b16..45198db50 100644 --- a/src/OneScript.StandardLibrary/Xml/XmlWriterImpl.cs +++ b/src/OneScript.StandardLibrary/Xml/XmlWriterImpl.cs @@ -25,9 +25,9 @@ public class XmlWriterImpl : AutoContext, IDisposable { private TextWriterWithSettings _internalTextWriter; private XmlTextWriter _writer; - private XmlWriterSettingsImpl _settings = (XmlWriterSettingsImpl)XmlWriterSettingsImpl.Constructor(); + private XmlWriterSettingsImpl _settings = XmlWriterSettingsImpl.Constructor(); private int _depth; - private Stack> _nsmap = new Stack>(); + private readonly Stack> _nsmap = new(); private StringBuilder _stringBuffer; private const string DEFAULT_INDENT_STRING = " "; @@ -51,6 +51,12 @@ private void ExitScope() --_depth; } + private void CheckIfOpen() + { + if (_writer == null) + throw NotOpenException(); + } + #region Properties [ContextProperty("Отступ","Indent")] @@ -77,8 +83,9 @@ public XmlWriterSettingsImpl Settings [ContextMethod("ЗаписатьАтрибут","WriteAttribute")] public void WriteAttribute(string localName, string valueOrNamespace, string value = null) - { - if(value == null) + { + CheckIfOpen(); + if (value == null) { _writer.WriteAttributeString(localName, valueOrNamespace); } @@ -91,30 +98,35 @@ public void WriteAttribute(string localName, string valueOrNamespace, string val [ContextMethod("ЗаписатьБезОбработки","WriteRaw")] public void WriteRaw(string data) { + CheckIfOpen(); _writer.WriteRaw(data); } [ContextMethod("ЗаписатьИнструкциюОбработки","WriteProcessingInstruction")] public void WriteProcessingInstruction(string name, string text) { + CheckIfOpen(); _writer.WriteProcessingInstruction(name, text); } [ContextMethod("ЗаписатьКомментарий","WriteComment")] public void WriteComment(string text) { + CheckIfOpen(); _writer.WriteComment(text); } [ContextMethod("ЗаписатьКонецАтрибута","WriteEndAttribute")] public void WriteEndAttribute() { + CheckIfOpen(); _writer.WriteEndAttribute(); } [ContextMethod("ЗаписатьКонецЭлемента","WriteEndElement")] public void WriteEndElement() { + CheckIfOpen(); _internalTextWriter.TrimEndSlashes = true; _writer.WriteEndElement(); _internalTextWriter.TrimEndSlashes = false; @@ -124,7 +136,8 @@ public void WriteEndElement() [ContextMethod("ЗаписатьНачалоАтрибута","WriteStartAttribute")] public void WriteStartAttribute(string name, string ns = null) { - if(ns == null) + CheckIfOpen(); + if (ns == null) { _writer.WriteStartAttribute(name); } @@ -138,6 +151,7 @@ public void WriteStartAttribute(string name, string ns = null) [ContextMethod("ЗаписатьНачалоЭлемента","WriteStartElement")] public void WriteStartElement(string name, string ns = null) { + CheckIfOpen(); if (ns == null) { _writer.WriteStartElement(name); @@ -152,12 +166,14 @@ public void WriteStartElement(string name, string ns = null) [ContextMethod("ЗаписатьОбъявлениеXML","WriteXMLDeclaration")] public void WriteXMLDeclaration() { + CheckIfOpen(); _writer.WriteStartDocument(); } [ContextMethod("ЗаписатьСекциюCDATA","WriteCDATASection")] public void WriteCDATASection(string data) { + CheckIfOpen(); _writer.WriteCData(data); } @@ -171,18 +187,21 @@ public void WriteNamespaceMapping(string prefix, string uri) [ContextMethod("ЗаписатьСсылкуНаСущность","WriteEntityReference")] public void WriteEntityReference(string name) { + CheckIfOpen(); _writer.WriteEntityRef(name); } [ContextMethod("ЗаписатьТекст","WriteText")] public void WriteText(string text) { + CheckIfOpen(); _writer.WriteString(text); } [ContextMethod("ЗаписатьТекущий","WriteCurrent")] public void WriteCurrent(XmlReaderImpl reader) { + CheckIfOpen(); var nodeType = reader.NodeType.UnderlyingValue; switch (nodeType) { @@ -225,7 +244,8 @@ public void WriteCurrent(XmlReaderImpl reader) case XmlNodeType.Document: case XmlNodeType.DocumentFragment: case XmlNodeType.Notation: - throw new RuntimeException(new Localization.BilingualString($"Копирование узла {nodeType} не поддерживается")); + throw CopyingNotSupportedException(nodeType); + default: break; } @@ -292,7 +312,8 @@ private static (string prefix, string localName) splitName(string nameOrLocalNam [ContextMethod("ЗаписатьТипДокумента","WriteDocumentType")] public void WriteDocumentType(string name, string varArg2, string varArg3 = null, string varArg4 = null) { - if(varArg4 != null) + CheckIfOpen(); + if (varArg4 != null) { _writer.WriteDocType(name, varArg2, varArg3, varArg4); } @@ -309,6 +330,7 @@ public void WriteDocumentType(string name, string varArg2, string varArg3 = null [ContextMethod("НайтиПрефикс","LookupPrefix")] public IValue LookupPrefix(string uri) { + CheckIfOpen(); string prefix = _writer.LookupPrefix(uri); if (prefix == null) return ValueFactory.Create(); @@ -318,26 +340,24 @@ public IValue LookupPrefix(string uri) [ContextMethod("Закрыть","Close")] public IValue Close() { - if(IsOpenForString()) + if (_writer==null) + return ValueFactory.Create(String.Empty); + + _writer.Flush(); + _writer.Close(); + Dispose(); + + if (IsOpenForString()) { - _writer.Flush(); - _writer.Close(); - - Dispose(); - var result = _stringBuffer.ToString(); _stringBuffer = null; + return ValueFactory.Create(result); } else { - _writer.Flush(); - _writer.Close(); - Dispose(); - - return ValueFactory.Create(); + return ValueFactory.Create(String.Empty); } - } private void ApplySettings(BslValue encodingOrSettings) @@ -477,9 +497,7 @@ protected override void Dispose(bool disposing) public void Dispose() { - if (_writer != null) - _writer.Close(); - + _writer?.Close(); _writer = null; } @@ -490,5 +508,19 @@ public static XmlWriterImpl Create() } public XmlWriter GetNativeWriter() => _writer; + + public static RuntimeException NotOpenException() + { + return new RuntimeException + ("Приемник данных XML не открыт", + "XML data target is not opened"); + } + public static RuntimeException CopyingNotSupportedException(XmlNodeType nodeType) + { + return new RuntimeException + ($"Копирование узла типа {nodeType} не поддерживается", + $"Copying a node of type {nodeType} is not supported"); + } + } } diff --git a/tests/xmlwrite.os b/tests/xmlwrite.os index 5b3e4665f..0d2c426f5 100644 --- a/tests/xmlwrite.os +++ b/tests/xmlwrite.os @@ -43,6 +43,9 @@ ВсеТесты.Добавить("ТестДолжен_ЗаписатьТекущий_ИнструкцииОбработки"); ВсеТесты.Добавить("ТестДолжен_ЗаписатьТекущий_ОбъявлениеИТипДокумента"); + + ВсеТесты.Добавить("ТестДолжен_ПроверитьЗакрытиеПустого"); + ВсеТесты.Добавить("ТестДолжен_ПроверитьТипВозвратаЗакрыть_ИзФайла"); Возврат ВсеТесты; @@ -759,3 +762,21 @@ ЧтениеXML.Прочитать(); юТест.ПроверитьРавенство(ЧтениеXML.ТипУзла, ТипУзла, Сообщение); КонецПроцедуры + +Процедура ТестДолжен_ПроверитьЗакрытиеПустого() Экспорт + Запись = Новый ЗаписьXML; + Результат = Запись.Закрыть(); + + юТест.ПроверитьРавенство(ТипЗнч(Результат), Тип("Строка")); + юТест.ПроверитьРавенство(Результат, ""); +КонецПроцедуры + +Процедура ТестДолжен_ПроверитьТипВозвратаЗакрыть_ИзФайла() Экспорт + Запись = Новый ЗаписьXML; + ИмяФайла = юТест.ИмяВременногоФайла("xml"); + Запись.ОткрытьФайл(ИмяФайла); + Результат = Запись.Закрыть(); + + юТест.ПроверитьРавенство(ТипЗнч(Результат), Тип("Строка")); + юТест.ПроверитьРавенство(Результат, ""); +КонецПроцедуры From 2e6af73b2d85ccc4db9bda2d1ab61aea43649d63 Mon Sep 17 00:00:00 2001 From: Mr-Rm Date: Mon, 29 Jun 2026 15:47:16 +0400 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=D0=BF=D1=80=D0=BE=D0=BF=D1=83=D1=89?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D0=B0=D1=8F=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/OneScript.StandardLibrary/Xml/XmlWriterImpl.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OneScript.StandardLibrary/Xml/XmlWriterImpl.cs b/src/OneScript.StandardLibrary/Xml/XmlWriterImpl.cs index 45198db50..abb1b3d48 100644 --- a/src/OneScript.StandardLibrary/Xml/XmlWriterImpl.cs +++ b/src/OneScript.StandardLibrary/Xml/XmlWriterImpl.cs @@ -180,6 +180,7 @@ public void WriteCDATASection(string data) [ContextMethod("ЗаписатьСоответствиеПространстваИмен","WriteNamespaceMapping")] public void WriteNamespaceMapping(string prefix, string uri) { + CheckIfOpen(); _writer.WriteAttributeString("xmlns", prefix, null, uri); _nsmap.Peek()[prefix] = uri; }