2013-07-09 6 views
0

Я хочу написать таблицу стилей XSLT, которая сопоставляет имена элементов с помощью некоторых правил сопоставления. Чтобы сделать таблицу стилей настраивается для менее опытных пользователей, я хочу, чтобы хранить карту seperatly как это внутри таблицы стилей:Имена элементов сопоставления XSLT

<mr:mapping-rules> 
    <field src="field1" dest="field1337" /> 
    <field src="field2" dest="field2" /> 
    <field src="field3" dest="field3" /> 
</mr:mapping-rules> 

Вот некоторые примеры входных данных:

<Record> 
    <field1>123</field1> 
    <field2>asd</field2> 
    <field3>456</field3> 
</Record> 

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

<Record> 
    <field1337>123</field1337> 
    <field2>asd</field2> 
    <field3>456</field3> 
</Record> 

Было бы хорошо, если бы кто-нибудь мог дать мне подсказку, как должен выглядеть шаблон.

+0

Прежде всего я хотел бы предложить, чтобы не перечислить поля, которые не должен быть изменен. Затем я задаюсь вопросом, не нужно ли отображать контекст, как путь родителя или предка. И я предложил бы затем решить проблему, написав одну таблицу стилей, которая берет файл сопоставления и создает новую таблицу стилей, которая реализует конкретное сопоставление для данного файла сопоставления. –

ответ

1

Вот предложение, основанное на комментарии, который я сделал. Я написал один таблицу стилей принимает файл отображения в виде

<mr:mapping-rules xmlns:mr="http://example.com/mr"> 
    <context pattern="Record"> 
    <field src="field1" dest="field1337" /> 
    </context> 
</mr:mapping-rules> 

для создания таблицы стилей в виде

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="@* | node()"> 
     <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Record/field1"> 
     <xsl:element name="field1337"> 
     <xsl:apply-templates select="@* | node()"/> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

Стилевой, что создает выше таблицу стилей, как его выход

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:mr="http://example.com/mr" 
    xmlns:oxsl="http://example.com/xsl" 
    exclude-result-prefixes="oxsl mr"> 

<xsl:namespace-alias stylesheet-prefix="oxsl" result-prefix="xsl"/> 

<xsl:output indent="yes"/> 

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

<xsl:template match="mr:mapping-rules/context/field"> 
    <oxsl:template match="{../@pattern}/{@src}"> 
    <oxsl:element name="{@dest}"> 
     <oxsl:apply-templates select="@* | node()"/> 
    </oxsl:element> 
    </oxsl:template> 
</xsl:template> 

</xsl:stylesheet> 

Затем вы можете запустить созданную таблицу стилей на входе, таком как

<Root> 
    <Record-List> 
    <Record> 
     <field1>foo</field1> 
     <field2>bar</field2> 
     <field3>baz</field3> 
    </Record> 
    </Record-List> 
</Root> 

и выводит

<Root> 
    <Record-List> 
    <Record> 
     <field1337>foo</field1337> 
     <field2>bar</field2> 
     <field3>baz</field3> 
    </Record> 
    </Record-List> 
</Root> 

Конечно файл отображение может быть адаптирован к вашим потребностям, в основном я пытался показать образец, генерирующий вторую таблицу стилей из файла отображения, чтобы затем быть применены к входной выборке.

+0

Хорошее решение. Существует много таких случаев, когда уместно думать о входных данных как определении набора правил преобразования, которые могут быть переведены в правила преобразования XSLT с использованием самого XSLT. –

+0

Это отличное решение, спасибо! –

1

решение Мартина является хорошим, в том, что подход является очень мощным и расширяемым, но это также можно решить проблему более непосредственно:

<xsl:key name="mappings" match="mr:mapping-rules/field" use="@src"/> 

<xsl:template match="*"> 
    <xsl:element name="{(key('mappings', name())/@dest, name())[1]}"> 
    <xsl:copy-of select="@*"/> 
    <xsl:apply-templates/> 
    <xsl:element> 
</xsl:template> 
+0

Это более короткий путь решения проблемы. Но я думаю, что я буду использовать более гибкое решение выше. Тем не менее спасибо за ответ! –

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