Как изменить значения атрибутов корневого узла и URL-адреса пространства имен - PullRequest
2 голосов
/ 09 декабря 2010

Я хочу изменить значения URL-адреса пространства имен XML. У меня есть xml, как показано ниже

<catalog xmlns="http://someurl"
         xmlns:some="http://someurl2"
         xsi:schemaLocation="http://someurl some.3.0.xsd"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <cd>
        <title>Empire Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>
            <name>Columbia</name>
        </company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
</catalog>

Я использую преобразование личности. Есть ли способ, которым я могу изменить текст в пространстве имен ursl? Например, я хочу изменить URL-адреса 'http://someurl' на' http://someur2' и 'http://someurl some.3.0.xsd' до 'http://someurl some.4.0.xsd'

1 Ответ

10 голосов
/ 09 декабря 2010

Это должно сделать это:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0"
   xmlns:old="http://someurl" exclude-result-prefixes="old">
   <!-- Identity transform -->
   <xsl:template match="@* | node()">
      <xsl:copy>
         <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
   </xsl:template>

   <!-- replace namespace of elements in old namespace -->
   <xsl:template match="old:*">
      <xsl:element name="{local-name()}" namespace="http://someurl2">
         <xsl:apply-templates select="@* | node()"/>
      </xsl:element>
   </xsl:template>

   <!-- replace xsi:schemaLocation attribute -->
   <xsl:template match="@xsi:schemaLocation">
      <xsl:attribute name="xsi:schemaLocation">http://someurl some.4.0.xsd</xsl:attribute>
   </xsl:template>
</xsl:stylesheet>

При вводе образца это дает:

<?xml version="1.0" encoding="utf-8"?>
<catalog xmlns="http://someurl2"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://someurl some.4.0.xsd">
   <cd>
      <title>Empire Burlesque</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>
         <name>Columbia</name>
      </company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
</catalog>

Пояснение:

Последние два шаблона, добавленные в преобразование идентификации, являются более конкретными и поэтому имеют более высокий приоритет по умолчанию, чем шаблон идентификации. Они переопределяют шаблон идентификации для элементов в «старом» пространстве имен и атрибутах xsl: schemaLocation, соответственно.

Шаблон для "old: ​​*" выводит элемент с тем же локальным именем, что и тот, который он заменяет (то есть имя без пространства имен), и дает ему новое желаемое пространство имен.

К счастью, процессор XSLT (или, точнее, сериализатор; я использую Saxon 6.5.5 для своего теста) решил сделать это новое пространство имен значением по умолчанию, поэтому он добавил объявление пространства имен по умолчанию для него в выходной корень элемент. Мы не просили это сделать, и теоретически не должно иметь значения, является ли это новое пространство имен значением по умолчанию или использует префикс. Но вы, кажется, хотите, чтобы он был по умолчанию, чтобы он работал хорошо.

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