Сохранение пространства имен в XML после преобразования XSLT - PullRequest
0 голосов
/ 15 февраля 2019

Это мой входной XML

<?xml version="1.0"?>
<myroot xmlns="http://www.myroot.com/v0.1" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <A>TestProject1</A>
 <B>ValueB</B>

</myroot>

Я хочу изменить пространство имен по умолчанию на 0,2 и добавить некоторые новые атрибуты через XSLT-преобразование.Я могу это сделать, но в моем выводе xml старые псевдонимы пространства имен не сохраняются, например xmlns: xsd и xmlns: xsi.

Кто-нибудь указывает, что не так с моим xslt.

Здесьмой XSLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:previous="http://www.myroot.com/v0.1">    
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
 <xsl:template match="node()|@*">
<!-- Copy the current node -->
<xsl:copy >
   <!-- Including any attributes it has and any child nodes -->
  <xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="previous:myroot">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()" />
        <xsl:element name="NewElement">1234</xsl:element>
    </xsl:copy>

</xsl:template>

<xsl:template
    match="//*[namespace-uri()='http://www.myroot.com/v0.1']">
    <xsl:element name="{local-name()}"
                 namespace="http://www.myroot.com/v0.2">
        <xsl:apply-templates select="@*|node()" />
    </xsl:element>
</xsl:template>
</xsl:stylesheet>

и это выходной xml (с отсутствующими пространствами имен xsi и xsd)

<?xml version="1.0"?>
<myroot xmlns="http://www.myroot.com/v0.2" >
 <A>TestProject1</A>
 <B>ValueB</B>
  <NewElement>1234</NewElement>
</myroot>

, но * ожидаемый результат -

<?xml version="1.0"?>
<myroot xmlns="http://www.myroot.com/v0.1" 
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <A>TestProject1</A>
 <B>ValueB</B>
 <NewElement>1234</NewElement>
</myroot>

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Одним из решений может быть: ( оптимизация бита )

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:previous="http://www.myroot.com/v0.1"
xmlns:new="http://www.myroot.com/v0.2"
version="1.0">

<xsl:output method="xml" indent="yes" />


<xsl:template match="previous:*">

 <xsl:element name="{local-name()}" namespace="http://www.myroot.com/v0.2">
    <xsl:copy-of select="@* | namespace::*[not(. = 'http://www.myroot.com/v0.1')]"/>
        <xsl:choose>
            <xsl:when test="local-name() = 'myroot'">
                <xsl:element name="NewElement">1234</xsl:element>
                <xsl:apply-templates/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:apply-templates/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / bFN1y8X / 6

0 голосов
/ 15 февраля 2019

Я бы предложил явно скопировать узлы пространства имен:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:previous="http://www.myroot.com/v0.1"
    version="1.0">

<xsl:template match="previous:*">
    <xsl:element name="{local-name()}" namespace="http://www.myroot.com/v0.2">
        <xsl:copy-of select="@* | namespace::*[not(. = 'http://www.myroot.com/v0.1')]"/>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / bFN1y8X

Если вы хотите добавить новый элементвнутри определенного элемента, такого как корневой элемент, добавьте для этого дополнительный шаблон.Также возможно переместить новое пространство имен в корневой элемент таблицы стилей, если вам нужно использовать его для всех элементов результата:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:previous="http://www.myroot.com/v0.1"
    exclude-result-prefixes="previous"
    xmlns="http://www.myroot.com/v0.2"
    version="1.0">

<xsl:output indent="yes"/>

<xsl:template match="previous:*">
    <xsl:element name="{local-name()}">
        <xsl:copy-of select="@* | namespace::*[not(. = 'http://www.myroot.com/v0.1')]"/>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

<xsl:template match="/previous:*">
    <xsl:element name="{local-name()}">
        <xsl:copy-of select="@* | namespace::*[not(. = 'http://www.myroot.com/v0.1')]"/>
        <xsl:apply-templates/>
        <NewElement>1234</NewElement>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / bFN1y8X / 4

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...