Warning
Данная статья не претендует на оригинальность и не является конечным решением. Подходы решения задач и примеры программного кода несут исключительно обучающий характер. |
Шаблон задачи области применения: есть произвольная таблица значений, к примеру, выгрузка результата запроса, которую необходимо передать в другую систему через COM, веб сервис или что-то еще . Для чтения таблицы значений без ошибок обращения к ссылкам необходимо преобразовать ссылки в GUID-ы.
Алгоритм преобразования:
- Таблица значений в xml:
ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку("UTF-8"); ЗаписьXML.ЗаписатьОбъявлениеXML(); СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ТаблицаДанных); СтрокаXML = ЗаписьXML.Закрыть();
- Преобразователь XSL:
ПреобразованиеXSL = Новый ПреобразованиеXSL; ПреобразованиеXSL.ЗагрузитьИзСтроки(СтрокаПравило); СтрокаРезультат = ПреобразованиеXSL.ПреобразоватьИзСтроки(СтрокаXML);
-
Новая строка xml в таблицу значений:
ЧтениеXML = Новый ЧтениеXML; ЧтениеXML.УстановитьСтроку(СтрокаРезультат); ТаблицаДанных = СериализаторXDTO.ПрочитатьXML(ЧтениеXML); ЧтениеXML.Закрыть();
Пример запроса одной ссылки:
ВЫБРАТЬ ПЕРВЫЕ 1
ИдентификаторыОбъектовМетаданных.Ссылка КАК Ссылка
ИЗ
Справочник.ИдентификаторыОбъектовМетаданных КАК ИдентификаторыОбъектовМетаданных
Пример xml, созданный через СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ТаблицаДанных):
<?xml version="1.0" encoding="UTF-8"?>
<ValueTable xmlns="http://v8.1c.ru/8.1/data/core" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<column>
<Name xsi:type="xs:string">Ссылка</Name>
<ValueType>
<Type>Null</Type>
<Type xmlns:d4p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d4p1:CatalogRef.ИдентификаторыОбъектовМетаданных</Type>
</ValueType>
<Title>Ссылка</Title>
<Width xsi:type="xs:decimal">25</Width>
</column>
<row>
<Value xmlns:d3p1="http://v8.1c.ru/8.1/data/enterprise/current-config" xsi:type="d3p1:CatalogRef.ИдентификаторыОбъектовМетаданных">627a6fb8-872a-11e3-bb87-005056c00008</Value>
</row>
</ValueTable>
Нужный результат:
<?xml version="1.0" encoding="utf-8"?>
<ValueTable xmlns="http://v8.1c.ru/8.1/data/core" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<column>
<Name xsi:type="xs:string">Ссылка</Name>
<ValueType>
<Type>Null</Type>
<Type xmlns:d4p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d4p1:CatalogRef.ИдентификаторыОбъектовМетаданных</Type>
<Type>xs:string</Type></ValueType>
<Title>Ссылка</Title>
<Width xsi:type="xs:decimal">25</Width>
</column>
<row>
<Value xmlns:d3p1="http://v8.1c.ru/8.1/data/enterprise/current-config" xsi:type="xs:string">627a6fb8-872a-11e3-bb87-005056c00008</Value>
</row>
</ValueTable>
Правило трансформации XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:ones="http://v8.1c.ru/8.1/data/core"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- установим способ вывода результата -->
<xsl:output method="xml" encoding="utf-8"/>
<!-- скопируем все узлы документа -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!-- добавим тип строка во все колонки -->
<xsl:template match="ones:column/ones:ValueType">
<xsl:copy>
<xsl:apply-templates/>
<xsl:if test="not(ones:Type[contains(node(), 'xs:string')])">
<xsl:element namespace="http://v8.1c.ru/8.1/data/core" name="Type"
>xs:string</xsl:element>
</xsl:if>
</xsl:copy>
</xsl:template>
<!-- во всех строках где значение строка длинной 36 символов заменить тип на строку -->
<xsl:template match="ones:row/ones:Value">
<xsl:copy>
<xsl:choose>
<xsl:when test="string-length(current()) = 36">
<xsl:attribute name="xsi:type">
<xsl:value-of select="'xs:string'"/>
</xsl:attribute>
<xsl:apply-templates select="node()"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="@* | node()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Итоги:
- Вполне работоспособный преобразователь;
- Нет времени проверять, но это вероятнее всего быстрее, чем программное добавление колонки и обход таблицы значений в цикле с получением GUID-а по каждой ссылке.
Спасибо за внимание.
«Нет времени проверять, но это вероятнее всего быстрее…» — вот это как раз крайне интересно.
Методика интересная как пример или шаблон. Если потребуется заменить тип значения только в одной колонке с таким-то именем. Здесь что писать?
+100500 работе с XSLT. Использую для преобразования xml в таблицу значений
соглашусь с тем, что главное тут это замер быстродействия
данный метод однозначно сложнее чем простой обход тз в цикле с получением гуидов
когда критично быстродействие сам пользую вариант с получением гуидов компоновкой данных (программное создание компоновки на стороне источника через ком)
(4) А не подскажете, есть какая-то специальная возможность в СКД получения GUID или вы говорите про вычисляемое поле, в котором можно получить GUID?
Заранее благодарю.
(5) Скорее всего имеется в виду вычисляемое поле с функцией XMLСтрока()