Выбор узлов с пространством имен по умолчанию - PullRequest
1 голос
/ 17 июня 2009

У меня есть XML-документ с множеством используемых пространств имен и схема для проверки. Схема требует, чтобы все элементы были «квалифицированными», и я предполагаю, что это означает, что они должны иметь полные QNames без пустого пространства имен.

Однако некоторые элементы в этом гигантском XML-документе проскользнули, используя только пространство имен по умолчанию, которое в случае с этим документом пустое. Обычно они не проходят проверку со схемой.

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

<x:doc xmlns:x="http://thisns.com/">
  <x:node @x:property="true">
     this part passes validation
  </x:node>
  <node property="false">
     this part does not pass validation
  </node>
</x:doc>

Я пытался добавить xmlns="http://thisns.com/" к корневому узлу документа, но это не согласуется с валидатором схемы. Любые мысли о том, как я могу сделать эту работу?

Спасибо!

1 Ответ

3 голосов
/ 17 июня 2009
<!-- Identity transform by default -->
<xsl:template match="node() | @*">
  <xsl:copy>
    <xsl:apply-templates select="node() | @*"/>
  </xsl:copy>
</xsl:template>
<!-- Override identity transform for elements with blank namespace -->
<xsl:template match="*[namespace-uri() = '']">    
  <xsl:element name="{local-name()}" namespace="http://thisns.com/">
    <xsl:apply-templates select="node() | @*"/>
  </xsl:element>
</xsl:template>
<!-- Override identity transform for attributes with blank namespace -->
<xsl:template match="@*[namespace-uri() = '']">
  <xsl:attribute name="{local-name()}" namespace="http://thisns.com/"><xsl:value-of  select="."/></xsl:attribute>
</xsl:template>

Это даст результат, похожий на:

<x:doc xmlns:x="http://thisns.com/">
  <x:node x:property="true">
    this part passes validation
  </x:node>
  <node xp_0:property="false" xmlns="http://thisns.com/" xmlns:xp_0="http://thisns.com/">
     this part does not pass validation
  </node>
</x:doc>

Обратите внимание, что второй по-прежнему без префикса пространства имен, но теперь считается частью того же пространства имен из-за атрибута xmlns =.

...