XSLT1.0 :: Я хочу добавить новый элемент в XML с суффиксом и пространством имен в качестве родительского

#xml #xslt #xslt-1.0

#xml #xslt #xslt-1.0

Вопрос:

Решение требуется только в XSLT1.0. Я хочу создать единый xslt, который будет работать, добавляя элемент независимо от пространства имен в фиксированном положении. Я хочу добавить элемент sas_api_key, как видно на выходе обоих XML-файлов

Ввод XML 1:

 <?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body xmlns:get="http://tempuri.org/getScreeningProfile">
        <get:getScreeningProfile>
            <get:parameters>
                <get:party_number>334857</get:party_number>
            </get:parameters>
        </get:getScreeningProfile>
    </soap:Body>
</soap:Envelope>
  

Вывод XML 1:

 <?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body xmlns:get="http://tempuri.org/getScreeningProfile">
        <get:getScreeningProfile>
            <get:parameters>
                <get:sas_api_key>123<get:sas_api_key>
                <get:party_number>334857</get:party_number>
            </get:parameters>
        </get:getScreeningProfile>
    </soap:Body>
</soap:Envelope>
  

Ввод XML2:

 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:biw="http://www.sas.com/xml/namespace/biwebservices">
    <soapenv:Header/>
    <soapenv:Body>
        <biw:getScreeningProfile_v2>
            <biw:parameters>
                <biw:sas_api_key>123<biw:sas_api_key>
                <biw:party_number>12345</biw:party_number>
            </biw:parameters>
        </biw:getScreeningProfile_v2>
    </soapenv:Body>
</soapenv:Envelope>
  

Вывод XML2:

 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:biw="http://www.sas.com/xml/namespace/biwebservices">
    <soapenv:Header/>
    <soapenv:Body>
        <biw:getScreeningProfile_v2>
            <biw:parameters>
                <biw:sas_api_key>123<biw:sas_api_key>
                <biw:party_number>12345</biw:party_number>
            </biw:parameters>
        </biw:getScreeningProfile_v2>
    </soapenv:Body>
</soapenv:Envelope>
  

Ниже приведен XSLT, который я создал, но он работает не так, как ожидалось. Пожалуйста, помогите.

 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    <xsl:template match="*">
        <xsl:copy>
            <xsl:apply-templates select="//*[local-name()='parameters']/*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="//*[local-name()='parameters']/*">
        <xsl:element name="sas_api_key" inherit-namespaces="yes">
            <xsl:apply-templates select="node()|@*"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>
  

Комментарии:

1. Могут parameters ли иметь префиксы и / или пространства имен, отличные от двух, показанных в ваших примерах?

Ответ №1:

В XSLT 1.0 вы могли бы сделать:

 <xsl:template match="*[local-name()='parameters']">
    <xsl:copy>
        <xsl:element name="{substring-before(name(), ':')}:sas_api_key" namespace="{namespace-uri()}">123</xsl:element>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>
  

Обратите внимание, что это предполагает, что у parameters элемента есть префикс.


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

Комментарии:

1. Спасибо @michael.hor257k. Решение работает как шарм.