Как удалить пространство имен по умолчанию и сохранить остальные пространства имен с помощью XSLT? - PullRequest
4 голосов
/ 11 августа 2011

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

Ввод:

<prefix:request xmlns:prefix="urn1" xmlns:foo2="urn2" xmlns="urn1">
<element1 xmlns="">version1</element1>
<element2 xsi:type="prefix:requestA" xmlns=""/>
...
</element1>
</prefix:request>

Ожидаемый результат:

<prefix:request xmlns:prefix="urn1" xmlns:foo2="urn2">
<element1>version1</element1>
<element2 xsi:type="prefix:requestA"/>
...
</element1>
</prefix:request>

Образец XSLT для удаления пространств имен отфильтрует все пространства имен, включая префикс. Есть идеи, как решить этот конкретный случай?

Ответы [ 2 ]

1 голос
/ 11 августа 2011

Хорошо, фрагмент, который вы опубликовали, не является даже правильно сформированным XML, поэтому трудно сказать, чего вы хотите достичь, поскольку второе закрытие </element1> не имеет соответствующего открывающего тега и в качестве префикса xsiиспользуется, но никогда не объявляется.

Однако, если у вас есть

<prefix:request xmlns:prefix="urn1" xmlns:foo2="urn2" xmlns="urn1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<element1 xmlns="">version1</element1>
<element2 xsi:type="prefix:requestA" xmlns=""/>

</prefix:request>

, тогда таблица стилей

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

  <xsl:template match="*">
    <xsl:element name="{name()}" namespace="{namespace-uri()}">
      <xsl:copy-of select="namespace::*[local-name()]"/>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="@* | text() | comment() | processing-instruction()">
    <xsl:copy/>
  </xsl:template>

</xsl:stylesheet>

при применении с Saxon 6.5.5 выдаст

<?xml version="1.0" encoding="utf-8"?><prefix:request xmlns:prefix="urn1" xmlns:foo2="urn2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<element1>version1</element1>
<element2 xsi:type="prefix:requestA"/>

</prefix:request>
0 голосов
/ 11 августа 2011

Это короткое преобразование :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="*">
     <xsl:element name="{name()}" namespace="{namespace-uri()}">
       <xsl:copy-of select="@*|namespace::*[name()]"/>
       <xsl:apply-templates select="node()"/>
     </xsl:element>
 </xsl:template>
</xsl:stylesheet>

при применении к (серьезно искажено и должно быть исправлено) при условии XML-подобного ввода :

<prefix:request xmlns:xsi="Undefined !!!"
xmlns:prefix="urn1" xmlns:foo2="urn2"
xmlns="urn1">
    <element1 xmlns="">version1</element1>
    <element2 xsi:type="prefix:requestA" xmlns=""/> ...  
</prefix:request>

дает желаемый, правильный результат :

<prefix:request xmlns:prefix="urn1" xmlns:xsi="Undefined !!!" xmlns:foo2="urn2">
   <element1>version1</element1>
   <element2 xsi:type="prefix:requestA"/> ...  
</prefix:request>
...