2015-02-25 3 views
0

У вас есть XML-то вроде этого:XSLT для поддержки обратной совместимости

<q:foo 
     xmlns:q="http://www.example.com/foo-1_0" xmlns:p="http://www.example.com/common/goo-1_0" 
     xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://www.example.com/foo/foo-1_0.xsd"> 
     <p:payload> 
     <p:var-list> 
      <p:var> 
      <p:key>key1</p:key> 
      <p:value xsi:type="xs:string">string content</p:value> 
      </p:var> 
     </p:var-list> 
     </p:payload> 
    </q:foo> 

Однако, человек, который написал, что не знает, что истинный идентификатор пространства имен документа не http://www.example.com/foo-1_0, а не http://www.example.com/foo-1_1. Таким образом, вам нужна таблица стилей для обновления URL-адреса. Здесь идет xslt.

<?xml version="1.0" encoding="iso-8859-1"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:old="http://www.example.com/foo-1_0" 
    xmlns:q="http://www.example.com/foo-1_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:oldc="http://www.example.com/common/goo-1_0" xmlns:p="http://www.example.com/common/goo-1_1"> 
    <xsl:output omit-xml-declaration="yes" indent="yes" /> 
    <xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:namespace name="xs" select="'http://www.w3.org/2001/XMLSchema'" /> 
     <xsl:apply-templates select="node()|@*" /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="@xsi:schemaLocation"> 
    <xsl:attribute name="xsi:{'schemaLocation'}"> 
      <xsl:value-of select="'http://www.example.com/foo/foo-1_1.xsd'"/> 
     </xsl:attribute> 
    </xsl:template> 
    <xsl:template match="old:*"> 
    <xsl:element name="q:{local-name()}"> 
     <xsl:apply-templates select="node()|@*" /> 
    </xsl:element> 
    </xsl:template> 
    <xsl:template match="oldc:*"> 
    <xsl:element name="p:{local-name()}"> 
     <xsl:apply-templates select="node()|@*" /> 
    </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

и выход, как и ожидалось.

<q:foo xmlns:q="http://www.example.com/foo-1_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/foo/foo-1_1.xsd"> 
 
    <p:payload xmlns:p="http://www.example.com/common/goo-1_1"> 
 
    <p:var-list> 
 
     <p:var> 
 
     <p:key>key1</p:key> 
 
     <p:value xsi:type="xs:string">string content</p:value> 
 
     </p:var> 
 
    </p:var-list> 
 
    </p:payload> 
 
</q:foo>

Когда я пытаюсь проверить выходной XML, XSI: тип = «хз: строка» не получает решена за счет его не генерируется в формате вывода XML. Любой, пожалуйста, помогите мне, как включить следующее в foo элемент вывода xml?

xmlns:xs="http://www.w3.org/2001/XMLSchema" 

ответ

0

Вы можете использовать xsl:copy-of для копирования пространств имен в области видимости на элементе:

<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:old="http://www.example.com/foo-1_0" 
       xmlns:q="http://www.example.com/foo-1_1" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:oldc="http://www.example.com/common/goo-1_0" 
       xmlns:p="http://www.example.com/common/goo-1_1"> 
    <xsl:output omit-xml-declaration="yes" indent="yes" /> 

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

    <xsl:template name="CopyNamespaces"> 
    <xsl:copy-of select="namespace::*[. != 'http://www.example.com/foo-1_0' and 
             . != 'http://www.example.com/common/goo-1_0']"/> 
    </xsl:template> 

    <xsl:template match="@xsi:schemaLocation"> 
    <xsl:attribute name="{name()}"> 
     <xsl:text>http://www.example.com/foo/foo-1_1.xsd</xsl:text> 
    </xsl:attribute> 
    </xsl:template> 

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

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

А вот дополнительные фантазии версия этого CopyNamespaces шаблона, который также копирует пространства имен из самого XSLT, так что вы можете иметь декларацию пространства имен p в корневом элементе результирующего документа, а не ниже:

<xsl:template name="CopyNamespaces"> 
    <xsl:copy-of select="(. | document('')/*)/namespace::* 
           [. != 'http://www.example.com/foo-1_0' and 
           . != 'http://www.example.com/common/goo-1_0' and 
           . != 'http://www.w3.org/1999/XSL/Transform']"/> 
</xsl:template> 
1

Как вы используете XSLT 2.0 и уже знаете о <xsl:namespace name="xs" select="'http://www.w3.org/2001/XMLSchema'" /> вы можете просто положить его в шаблоне, где вы карты old:* к новым элементам, как корневой элемент является одним из тех, кого он будет иметь объявление пространства имен:

<xsl:template match="old:*"> <xsl:element name="q:{local-name()}"> <xsl:namespace name="xs" select="'http://www.w3.org/2001/XMLSchema'" /> <xsl:apply-templates select="node()|@*" /> </xsl:element> </xsl:template>

Смежные вопросы