Извлечь XML-фрагмент для использования в качестве вывода с префиксными модами

На самом деле это требуется для реализации любой структуры данных, которая выделяет больше памяти, чем минимально необходимое для количества вставленных элементов (т. е. ничего, кроме связанной структуры, которая выделяет один узел за раз).

Возьмите контейнеры наподобие unordered_map, vector или deque. Все они выделяют больше памяти, чем минимально требуется для вставленных вами элементов, чтобы избежать необходимости распределения кучи для каждой отдельной вставки. Давайте используем vector в качестве простейшего примера.

Когда вы это делаете:

vector<Foo> vec;

// Allocate memory for a thousand Foos:
vec.reserve(1000);

... который фактически не создает тысячу Foos. Он просто выделяет / резервирует память для них. Если vector не использовал здесь место размещения, это было бы построение по умолчанию Foos по всему месту, а также необходимость вызывать их деструкторы даже для элементов, которые вы никогда не вставили в первую очередь.

Allocation! = Construction, Freeing! = Destruction

Как правило, для реализации многих структур данных, подобных описанным выше, вы не можете рассматривать выделение памяти и создание элементов как одну неделимую вещь, и вы также не можете обрабатывать освобождение памяти и уничтожая элементы как одну неделимую вещь.

Должно быть разделение между этими идеями, чтобы избежать излишнего вызова конструкторов и деструкторов излишне левым и правым, и поэтому стандартная библиотека разделяет идею std::allocator (которая не создает или не уничтожает элементы, когда он выделяет / освобождает память *) вдали от используемых им контейнеров, которые вручную создают элементы, используя размещение новых и вручную уничтожая элементы, используя явные вызовы деструкторов.

  • Ненавижу дизайн std::allocator, но это другой предмет, о котором я не буду говорить. : -D

Так или иначе, я, как правило, очень сильно его использую, так как я написал несколько стандартных контейнеров C ++ общего назначения, которые нельзя было построить в условия существующих. Среди них была небольшая реализация векторов, которую я построил пару десятилетий назад, чтобы избежать распределения кучи в обычных случаях и эффективного управления памятью (не выделяет один узел за раз). В обоих случаях я не мог реализовать их с использованием существующих контейнеров, поэтому мне пришлось использовать placement new, чтобы избежать излишнего вызова конструкторов и деструкторов на ненужные вещи слева и справа.

Естественно, если вы когда-нибудь работаете с помощью пользовательских распределителей для выделения объектов по отдельности, например, в виде бесплатного списка, вы также обычно хотели бы использовать placement new, как это (основной пример, который не беспокоит безопасность исключений или RAII):

Foo* foo = new(free_list.allocate()) Foo(...);
...
foo->~Foo();
free_list.free(foo);
0
задан Keith Fosberg 5 March 2019 в 17:41
поделиться

2 ответа

Оказывается, мне не нужно было ничего делать со встроенным фрагментом. Конечная точка смогла понять пространство имен по умолчанию для встроенных документов (но если кто-то захочет ответить на это, я не буду возражать).

Единственное изменение, которое мне нужно было сделать, чтобы ответить Майклу, было добавить объявление пространства имен в тег "envelope". (Ни в коем случае Мишель не мог знать, что для завершения процесса понадобилось другое пространство имен.)

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fha="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard"
xmlns:client="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard"
xmlns:ns2="http://mismo.org/aus/" 
xmlns:ns1="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="/fha:TOTALRequest-Response-Keys">
    <soapenv:Envelope 
    	xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    	xmlns:f17="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard"
	xmlns:fha="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
        <soapenv:Body>
            <xsl:apply-templates select="fha:TOTALRequest-Response/client:process"/>
        </soapenv:Body>
    </soapenv:Envelope>
</xsl:template>

<xsl:template match="client:*">
    <xsl:element name="fha:{local-name()}">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

0
ответ дан Keith Fosberg 5 March 2019 в 17:41
поделиться

Будет ли это работать для вас?

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fha="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard"
xmlns:client="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="/fha:TOTALRequest-Response-Keys">
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:f17="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
        <soapenv:Body>
            <xsl:apply-templates select="fha:TOTALRequest-Response/client:process"/>
        </soapenv:Body>
    </soapenv:Envelope>
</xsl:template>

<xsl:template match="client:*">
    <xsl:element name="fha:{local-name()}">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>
0
ответ дан michael.hor257k 5 March 2019 в 17:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: