2013-02-21 2 views
2

Я редактирую большой документ Microsoft InfoPath. InfoPath использует XSLT для компоновки форм. Графический интерфейс очень громоздкий, и я хочу ускорить процесс, отредактировав внутренние таблицы стилей с помощью XSLT. Итак, вот интересная проблема XSLT: как вы применяете одну таблицу стилей XSLT к другой? Вот начало:Применить таблицу стилей к таблице стилей?

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:output method="xml" indent="yes"/> 

    <xsl:strip-space elements="*"/> 

    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="select"> 
    ... 
    <xsl:template> 

</xsl:stylesheet> 

То есть, я копирую все, но изменить < выберите > элементы. В шаблоне «select» я хочу фрагмент XSLT. Тем не менее, I не хотите, чтобы XSLT обрабатывался. Но I do хочу, чтобы у него было пространство имен XSLT, так что выход по-прежнему работает как стильный файл.

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

+0

Можете ли вы показать нам пример того, что вход и выход, что вы хотите? – SpringSteven

ответ

2

Это назначение <xsl:namespace-alias>

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
       xmlns:xslout="urn:dummy" 
       exclude-result-prefixes="xslout"> 
    <xsl:namespace-alias stylesheet-prefix="xslout" result-prefix="xsl" /> 

    <xsl:output method="xml" indent="yes"/> 

    <!-- ... --> 

    <xsl:template match="select"> 
    <xslout:value-of select="{@valueXpath}" /> 
    <xsl:template> 

</xsl:stylesheet> 

Здесь любые xslout: элементы в таблице стилей станет xsl: в выходных данных, а также любые шаблоны значений атрибутов в таких элементах будут обработаны это таблицы стилей (так в приведенном выше значении <select valueXpath="@foo" /> генерирует <xsl:value-of select="@foo" /> в качестве выхода). Если Вы хотите положить АВТ на выходе вы должны удвоить брекеты

<xslout:element name="{{@elementName}}" /> 

Если у вас уже есть куски <xsl:...> вещи, которые вы не хотите переписать, то вы можете использовать другой префикс, например,

<?xml version="1.0" encoding="utf-8"?> 
<sty:stylesheet xmlns:sty="http://www.w3.org/1999/XSL/Transform" version="1.0" 
       xmlns:xsl="urn:dummy" 
       exclude-result-prefixes="xsl"> 
    <sty:namespace-alias stylesheet-prefix="xsl" result-prefix="sty" /> 

    <sty:template match="select"> 
    <xsl:value-of select="{@valueXpath}" /> 
    <sty:template> 

хотя примечание об АВТ по-прежнему стоит.

Возможно, более простой альтернативой, если вы просто хотите, чтобы скопировать блок XSLT кода в select элемента дословно (вместо генерации он на основе содержимого select элемента) должен был бы поставить этот код XSLT в другой файл и использовать document функция

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:output method="xml" indent="yes"/> 

    <xsl:strip-space elements="*"/> 

    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="select"> 
    <xsl:copy-of select="document('to-insert.xml')/*/node()" /> 
    <xsl:template> 

</xsl:stylesheet> 

где to-insert.xml содержит что-то вроде

<data xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:for-each select="*"> 
    <!-- ... --> 
    </xsl:for-each> 
</data> 
+0

Спасибо Яну. Это был тот ответ, на который я надеялся. Я только что узнал еще одну функцию XSLT. Похоже, что префиксы exclude-result не нужны, поскольку данный тип-префикс заменяется на определение. –

2

Для вывода элементов XSLT в результирующий документ XML вы не можете использовать элементы так, как они есть, потому что, как вы сказали, они будут обрабатываться как XSLT. Однако вы можете использовать элемент < xsl: element> для вывода элементов XSLT.

Например,

<xsl:template match="select"> 
    <xsl:element name="xsl:apply-templates"> 
     <xsl:attribute name="select">*</xsl:attribute> 
    </xsl:element> 
<xsl:template> 

Это будет выводить для каждого выбора элемента,

<xsl:apply-templates select="*" /> 

Вы можете использовать < XSL: элемент> и < XSL: атрибут> для построения кода XSLT, что вам хочу быть выведенным.

UPDATE: в соответствии со сценарием у вас есть большой код XSLT, который должен быть выведен внутри выбора шаблона, так что будет много времени переписывать весь код с < XSL: элемент> и < XSL: атрибут>. Но вам не нужно тратить столько времени, потому что вы можете написать XSL-шаблон для преобразования XSLT, который входит в шаблон, соответствующий select, в XSL-код, написанный с помощью < xsl: element> и < xsl: attribute>.

Следующий код будет делать:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:myname="http://www.myname.co.uk/def"> 
    <xsl:output method="xml" indent="no"/> 


    <!-- Copy by default all elements which do not belong to the xsl namespace --> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*" /> 
     </xsl:copy> 
    </xsl:template> 

    <!-- Match elements which their namespace match the namespace matched with xsl --> 
    <xsl:template match="xsl:*"> 
     <!-- Transform all the elements to xsl:element name="xsl:element" nodes --> 
     <xsl:element name="xsl:element"> 
      <xsl:attribute name="name"> 
       <xsl:value-of select="name()" /> 
      </xsl:attribute> 
      <xsl:apply-templates select="@*" mode="xsl-attr" /> 
      <xsl:apply-templates select="node()" /> 
     </xsl:element> 
    </xsl:template> 

    <!-- Transform all the attributes to xsl:element name="xsl:attribute" --> 
    <xsl:template match="@*" mode="xsl-attr"> 
     <xsl:element name="xsl:attribute"> 
      <xsl:attribute name="name"> 
       <xsl:value-of select="local-name()" /> 
      </xsl:attribute> 
      <xsl:value-of select="." /> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

Таким образом, вы можете скопировать и вставить код, который вы получите от этого преобразования в шаблон сопоставления в избранные элементы.

+0

Спасибо, Пабло. Я не сомневаюсь, что это сработает. Моя проблема заключается в том, что куски довольно большие, поэтому их переписывание с использованием элементов xsl: element и xsl: атрибутов будет трудоемким и подверженным ошибкам. Это не стоит делать для таблицы стилей, которая предназначена для применения всего несколько раз. Тем не менее, можно подумать и в других случаях! –

+0

Я обновил свой ответ, посмотрю. –

+1

Итак, вы только что создали таблицу мета-мета-стилей, чтобы преобразовать таблицу стилей в таблицу мета-стилей, которая при запуске выведет таблицу стилей, о которой вы впервые подумали. Nice :-) –

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