2016-07-01 2 views
1

Вопрос заключается в следующем, у меня есть простой XML-файл:перезапись XMLNS ломает XSLT результата

<table xmlns="http://www.w3.org/TR/html4/"> 
    <tr> 
     <td> 
      Does not work 
     </td> 
    </tr> 
</table> 

и файл XSL tranformation

<xsl:transform version="1.0" xmlns="http://www.w3.org/TR/html4/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="td"> 
     It works 
    </xsl:template> 
</xsl:transform> 

Если «тд» сопоставляется я ожидаю увидеть «Он работает» как результат, определенный шаблоном. Если «td» не сопоставляется, тогда я ожидаю увидеть «Не работает», поскольку шаблоны по умолчанию выводят все значения узлов, не обрабатываемые настраиваемым шаблоном. Результат:

<?xml version="1.0"?> 


     Does not work 

Однако если изменить объявления пространства имен в Xmlns: HTML = "...", то результат меняется.

XML:

<html:table xmlns:html="http://www.w3.org/TR/html4/"> 
    <html:tr> 
     <html:td> 
      Does not work 
     </html:td> 
    </html:tr> 
</html:table> 

XSLT:

<xsl:transform version="1.0" xmlns:html="http://www.w3.org/TR/html4/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="html:td"> 
     It works 
    </xsl:template> 
</xsl:transform> 

результат:

<?xml version="1.0"?> 


    It works 

Это простой пример, чтобы изолировать проблему, XML, для реального применения обеспечивается стороннее программное обеспечение, переписывание объявления xmlns в xmlns: это не вариант. Мой вопрос: как мне заставить это работать, результат: «Он работает», без изменения xmlns.

Для преобразования Я использую notepad ++ с плагином XML-инструментов, где есть опция преобразования XSL.

Спасибо заранее

ответ

3

Transform первый документ (тот, который имеет по умолчанию пространство имен):

<table xmlns="http://www.w3.org/TR/html4/"> 
    <tr> 
     <td> 
      Does not work 
     </td> 
    </tr> 
</table> 

со второй таблицы стилей XSLT:

<xsl:transform version="1.0" xmlns:html="http://www.w3.org/TR/html4/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="html:td"> 
     It works 
    </xsl:template> 
</xsl:transform> 

и вы будете удивлены, в результате:

<?xml version="1.0" encoding="UTF-8"?> 


    It works 

Декларирование пространства имен с префиксом :

xmlns:html="http://www.w3.org/TR/html4/" 

обычный способ иметь дело с входными XML документами, которые имеют пространство имен по умолчанию. Если у вас есть такое объявление в вашей таблице стилей, то html:td будет означать то же самое, что и элемент td с пространством имен по умолчанию из входного документа.

Это потому, что префиксы на самом деле неактуальны.Префиксы, такие как html:, не имеют никакого значения, это URI пространства имен имеет смысл. Префиксы являются лишь сокращением, чтобы избежать необходимости вводить (или читать) URI пространства имен для каждого отдельного элемента. Вы должны думать элемента, как

<table xmlns="http://www.w3.org/TR/html4/"> 

в

<{http://www.w3.org/TR/html4/}table> 

и, аналогично, думаю

<html:table xmlns:html="http://www.w3.org/TR/html4/"> 

как же:

<{http://www.w3.org/TR/html4/}table> 

Кроме того, кратко комментируя:

<xsl:transform version="1.0" xmlns="http://www.w3.org/TR/html4/"> 

помнить, что таблицы стилей XSLT это просто обычный файл XML и все правила XML применяются к нему. Единственный эффект объявления пространства имен по умолчанию в таблице стилей XSLT: все элементы, которые не имеют префикса (т. Е. Не находятся в другом пространстве имен), будут связаны с этим пространством имен.

Но поскольку все элементы в вашей таблице стилей XSLT имеют префикс xsl:, пространство имен по умолчанию ничего не делает. В таблице стилей, как:

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform version="1.0" xmlns="http://www.w3.org/TR/html4/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/"> 
     <result>it works</result> 
    </xsl:template> 
</xsl:transform> 

вы можете увидеть, что делает пространство имен по умолчанию, так как результат будет:

<?xml version="1.0" encoding="UTF-8"?> 
<result xmlns="http://www.w3.org/TR/html4/">it works</result> 
+0

Это решает проблему, но я до сих пор не понимаю, почему не префикс ее не работает. Если префикс отсутствует, не будет ли оно по умолчанию объявлять пространство имен, объявленное xmlns, так как нет конфликта с другим пространством имен, я ожидал, что это сработает. – DemanB

+0

@DemanB "* Если префикса нет, не будет ли оно по умолчанию для пространства имен, объявленного xmlns *« Если префикса нет, тогда он будет выбирать элементы в пространстве имен. –

+1

@DemanB Пожалуйста, попробуйте объяснить это еще раз: ваше предположение состоит в том, что в элементах 'xsl: template' пространство имен по умолчанию, объявленное в элементе' xsl: transform', будет применяться к значению атрибута 'select'. Но пространства имен по умолчанию применяются только к элементам XML, никогда к атрибутам и никогда не относятся к значениям атрибутов. Есть функциональность, которая делает это, хотя я не рекомендую в этом случае: ['xpath-default-namespace'] (https://www.ibm.com/developerworks/library/x-xsltmistakes/#list4). Кроме того, он требует XSLT 2.0. –

1

Мой вопрос, как я могу получить эту работу, результат: «Это работает», без изменяющегося Xmlns.

<xsl:transform version="1.0" 
xmlns:ns="http://www.w3.org/TR/html4/" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="ns:td"> 
     It works 
</xsl:template> 

</xsl:transform> 
+0

Это правильный ответ, принял ответ Матиас Мюллер для дополнительной информации , Спасибо – DemanB

+0

"* принял ответ Матиаса Мюллера за дополнительной информацией. *« И поэтому вы должны! –