2014-11-13 3 views
0

Я думал, что это будет просто, но теперь я потратил около 4 часов на эту проблему. Все, что я хочу сделать, это изменить пространство имен по умолчанию этого XML:Замените пространство имен по умолчанию, используя XSL

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<scenarios xmlns="http://my.url/xmlns/scenarios/v1.0.0"> 
    <scenarios> 
     <scenario id="1" name="00_reset" active="true"> 
      <events> 
       <sensorevent id="1" name="resetButtonEvent"> 
        <sensors> 
         <sensor deviceid="46"/> 
        </sensors> 
       </sensorevent> 
      </events> 
     </scenario> 
    </scenarios> 
    <systemstates> 
     <systemstate id="1" default="true" name="00_visitor_reset" display="true" publish="true" type="BOOLEAN"/> 
    </systemstates> 
</scenarios> 

«v1.0.0» должен быть изменен на «v1.1.0». Но все, что я мог придумать это:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:old="http://my.url/xmlns/scenarios/v1.0.0" 
xmlns:new="http://my.url/xmlns/scenarios/v1.1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="old:*"> 
     <xsl:element name="{local-name()}" namespace="http://my.url/xmlns/scenarios/v1.1.0"> 
      <xsl:apply-templates select="@* | node()" /> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

, который производит:

<?xml version="1.0" encoding="UTF-8"?><ns0:scenarios xmlns:ns0="http://my.url/xmlns/scenarios/v1.1.0"> 
    <ns1:scenarios xmlns:ns1="http://my.url/xmlns/scenarios/v1.1.0"> 
     <ns2:scenario xmlns:ns2="http://my.url/xmlns/scenarios/v1.1.0" id="1" name="00_reset" active="true"> 
      <ns3:events xmlns:ns3="http://my.url/xmlns/scenarios/v1.1.0"> 
       <ns4:sensorevent xmlns:ns4="http://my.url/xmlns/scenarios/v1.1.0" id="1" name="resetButtonEvent"> 
        <ns5:sensors xmlns:ns5="http://my.url/xmlns/scenarios/v1.1.0"> 
         <ns6:sensor xmlns:ns6="http://my.url/xmlns/scenarios/v1.1.0" deviceid="46"/> 
        </ns5:sensors> 
       </ns4:sensorevent> 
      </ns3:events> 
     </ns2:scenario> 
    </ns1:scenarios> 
    <ns7:systemstates xmlns:ns7="http://my.url/xmlns/scenarios/v1.1.0"> 
     <ns8:systemstate xmlns:ns8="http://my.url/xmlns/scenarios/v1.1.0" id="1" default="true" name="00_visitor_reset" display="true" publish="true" type="BOOLEAN"/> 
    </ns7:systemstates> 
</ns0:scenarios> 

, который на самом деле не то, что я хочу, потому что единственное, что нужно изменить это объявление пространства имен в корневом элементе , Как я могу изменить пространство имен по умолчанию от http://my.url/xmlns/scenarios/v1.0.0 до http://my.url/xmlns/scenarios/v1.1.0 с использованием XSLT1.0 без добавления префиксов?

ответ

0

XSLT 1.0 позволяет XSLT-процессору выбирать любой префикс пространства имен, который ему нравится, поэтому этот вывод является совместимым, но очень недружественным. В XSLT 2.0 процессор должен выбрать префикс, который вы запрашиваете, если конфликт не существует, поэтому эта таблица стилей должна выдавать требуемый результат. Поэтому я думаю, что ваш выбор - запустить код через процессор XSLT 2.0 или через более удобный XSLT 1.0 процессор.

1

Попробуйте

<xsl:stylesheet version="1.0" xmlns:old="http://my.url/xmlns/scenarios/v1.0.0" 
xmlns="http://my.url/xmlns/scenarios/v1.1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="old:*"> 
     <xsl:element name="{local-name()}"> 
      <xsl:apply-templates select="@* | node()" /> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

Если это не поможет, то попробуйте другой XSLT 1.0 процессор.

+0

Это работает в XMLSpy (который не является XSLT1.0), но не с процессором Java. Я бы предпочел не менять процессор, но если нет другого способа, я должен это сделать. –

+1

Я не думаю, что есть что-то вроде процессора Java. Существуют различные процессоры XSLT 1.0, доступные для Java, например Saxon 6.5, или, например, Xalan от Apache.org. Я не думаю, что это проблема XSLT 1.0 против 2.0, хотя спецификация XSLT 2.0, вероятно, более конкретна в отношении того, какой результат сериализации является правильным. Попробуйте с Saxon 6.5 сравнить, я думаю, это даст вам результат, который вы хотите. Хотя в Java-мире я думаю, что переход к XSLT 2.0 с Saxon 9, как правило, является хорошим и легким шагом в любом случае. Вы ничего не можете изменить в коде XSLT. –

0

Теперь я переключился на саксон как XSLT-процессор и отобразил желаемый результат. Я хотел избежать дополнительных зависимостей, но, похоже, другого пути нет. Спасибо Мартин Хоннен и Майкл Кей!

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