Arhn - архитектура программирования

XSLT для добавления префиксных пространств имен всех узлов, кроме нескольких

Я пытаюсь написать код XSLT, чтобы добавить префиксные пространства имен ко всем узлам, кроме нескольких.

Пример XML:

    <BatchPrepareDeliverArchive xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="schema">
<BatchInformation>
    <RqUId>424000000071256187550913330</RqUId>
    <BatchFeedId>CMLTREXT4240</BatchFeedId>
    <BatchCount>7</BatchCount>
</BatchInformation>
<BatchDeliverArchive>
    <Transactions>
        <Transaction>
            <TransactionUUID>90022016-01-140000001</TransactionUUID>
            <CustomerData>
                <GBD_Transactions>
                    <GBD_Transaction>
                        <Common_Data>
                            <Transaction_ID>90022016-01-140000001</Transaction_ID>
                            </Common_Data>
                        <Templates>
                            <Template>
                                <Template_Name>A21_LETTER_FINAL_NOTICE_OF_CANCELLATION_TPA</Template_Name>
                                <Transaction_ID>90022016-01-140000001</Transaction_ID>
                                </Template>
                        </Templates>
                    </GBD_Transaction>
                </GBD_Transactions>
            </CustomerData>
            <DocInfo>
                <Name>OPERATION NAME</Name>
                </DocInfo>
            </Transaction>
            </Transactions>
            </BatchDeliverArchive>
    </BatchPrepareDeliverArchive>

Я хочу добавить префикс urn ко всем узлам, кроме GBD_Transactions и его дочерних элементов.

Я придумал этот XSLT:

    <xsl:stylesheet version="1.0"  xmlns:urn="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="@*">
    <xsl:element name="urn:{local-name()}">
    <xsl:value-of select="."/>
    </xsl:element>
    </xsl:template>

    </xsl:stylesheet>

Здесь трансформируются все узлы, что не является ожидаемым результатом. Был бы признателен за любую помощь в этом!

18.01.2016

Ответы:


1

В вашем шаблоне, соответствующем «*», вы должны различать это следующим образом:

<xsl:template match="*">
    <xsl:choose>
        <xsl:when test="ancestor-or-self::GBD_Transactions">
            <xsl:copy>
                <xsl:apply-templates"/>
            </xsl:copy>
        </xsl:when>
        <xsl:otherwise>
            <xsl:element name="urn:{local-name()}">
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

Вывод будет выглядеть так:

<urn:BatchPrepareDeliverArchive xmlns:urn="http://www.w3.org/2001/XMLSchema-instance">
    <urn:BatchInformation>
        <urn:RqUId>424000000071256187550913330</urn:RqUId>
        <urn:BatchFeedId>CMLTREXT4240</urn:BatchFeedId>
        <urn:BatchCount>7</urn:BatchCount>
    </urn:BatchInformation>
    <urn:BatchDeliverArchive>
        <urn:Transactions>
            <urn:Transaction>
                <urn:TransactionUUID>90022016-01-140000001</urn:TransactionUUID>
                <urn:CustomerData>
                    <GBD_Transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                        <GBD_Transaction>
                            <Common_Data>
                                <Transaction_ID>90022016-01-140000001</Transaction_ID>
                            </Common_Data>
                            <Templates>
                                <Template>
                                    <Template_Name>A21_LETTER_FINAL_NOTICE_OF_CANCELLATION_TPA</Template_Name>
                                    <Transaction_ID>90022016-01-140000001</Transaction_ID>
                                </Template>
                            </Templates>
                        </GBD_Transaction>
                    </GBD_Transactions>
                </urn:CustomerData>
                <urn:DocInfo>
                    <urn:Name>OPERATION NAME</urn:Name>
                </urn:DocInfo>
            </urn:Transaction>
        </urn:Transactions>
    </urn:BatchDeliverArchive>
</urn:BatchPrepareDeliverArchive>

Это то, что вы хотите?

18.01.2016
  • Спасибо Кимми за этот ответ. Вывод соответствует ожиданиям. Нельзя ли удалить объявление пространства имен из узла GBD_Transactions? 18.01.2016
  • Я могу справиться с этим пространством имен, спасибо. 18.01.2016

  • 2

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

    Попробуйте добавить этот шаблон в XSLT

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

    Обратите внимание, что сопоставление с конкретным именем элемента имеет более высокий приоритет, чем сопоставление с *, поэтому этот шаблон всегда следует использовать перед более общим.

    Кстати, есть проблема с вашим шаблоном, который соответствует "*". Вы, вероятно, изменить его на это...

    <xsl:template match="*">
      <xsl:element name="urn:{local-name()}">
        <xsl:apply-templates select="@*|node()" />
       </xsl:element>
    </xsl:template>
    

    Это связано с тем, что <xsl:apply-templates /> аналогично выполнению <xsl:apply-templates select="node()" /> и поэтому не будет выбирать атрибуты. Таким образом, ваш существующий шаблон, соответствующий @*, не будет вызываться иначе.

    РЕДАКТИРОВАТЬ: Если вы хотите, чтобы атрибут xsi:schemaLocation не стал элементом, добавьте и этот шаблон (вам нужно будет объявить пространство имен xsi в XSLT)

    <xsl:template match="@xsi:*">
        <xsl:copy />
    </xsl:template>
    

    Или, может быть, вы не хотите, чтобы какие-либо атрибуты были изменены на элементы? Попробуйте этот XSLT вместо этого?

    <xsl:stylesheet version="1.0"  xmlns:urn="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <xsl:output omit-xml-declaration="yes" indent="yes"/>
        <xsl:strip-space elements="*"/>
    
        <xsl:template match="*">
        <xsl:element name="urn:{local-name()}">
        <xsl:apply-templates select="@*|node()" />
        </xsl:element>
        </xsl:template>
    
        <xsl:template match="@*">
            <xsl:copy />
        </xsl:template>
    
        <xsl:template match="GBD_Transactions|GBD_Transactions//*|GBD_Transactions//@*">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()" />
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>
    
    18.01.2016
  • Привет Тим, Спасибо за ваш ответ. Однако я вижу, что атрибут xsi:schema преобразуется в текстовый узел. Кроме того, я не хочу объявлять пространство имен для GBD_Transactions. Есть ли способ удалить его? 18.01.2016
  • Я могу справиться с этим пространством имен, спасибо. 18.01.2016
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..