2016-09-29 4 views
2

У меня есть один основной xslt, который является cdcatalog.xsl и связан с файлом xml cdcatalog.xml.
Я пытаюсь применить шаблоны динамически на основе значения в country. Некоторые из фактических шаблонов являются внешними .xsl файлами.применять шаблон XSL динамически. Шаблон находится во внешнем файле xslt и включен в основной xslt

cdcatalog.xsl

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

    <xsl:include href="cdcatalog_in.xsl"/> 
    <xsl:include href="cdcatalog_usa.xsl"/> 
    <xsl:include href="cdcatalog_uk.xsl"/> 
    <xsl:template match="/"> 
    <html> 
    <body> 
    <h2>My CD Collection</h2> 
    <xsl:apply-templates /> 
    </body> 
    </html> 
    </xsl:template> 

    <xsl:template match="cd"> 
    <p> 
    <xsl:apply-templates select="title"/> 
    <xsl:apply-templates select="artist"/> 
    </p> 
    </xsl:template> 

    <xsl:template match="title"> 
    Title: <span style="color:#ff0000"> 
    <xsl:value-of select="."/></span> 
    <br /> 
    </xsl:template> 

    <xsl:template match="artist"> 
    Artist: <span style="color:#00ff00"> 
    <xsl:value-of select="."/></span> 
    <br /> 
    </xsl:template> 

    </xsl:stylesheet> 

cdcatalog.xml содержимое, как показано ниже:

<?xml version="1.0" encoding="UTF-8"?> 
    <?xml-stylesheet type="text/xsl" href="cdcatalog.xsl"?> 
    <catalog> 
    <cd> 
     <title>Empire Burlesque</title> 
     <artist>Bob Dylan</artist> 
     <country>USA</country> 
     <company>Columbia</company> 
     <price>10.90</price> 
     <year>1985</year> 
    </cd> 
    <cd> 
     <title>Hide your heart</title> 
     <artist>Bonnie Tyler</artist> 
     <country>UK</country> 
     <company>CBS Records</company> 
     <price>9.90</price> 
     <year>1988</year> 
    </cd> 
    <cd> 
     <title>Greatest Hits</title> 
     <artist>Dolly Parton</artist> 
     <country>USA</country> 
     <company>RCA</company> 
     <price>9.90</price> 
     <year>1982</year> 
    </cd> 
    <cd> 
     <title>Still got the blues</title> 
     <artist>Gary Moore</artist> 
     <country>IN</country> 
     <company>Virgin records</company> 
     <price>10.20</price> 
     <year>1990</year> 
    </cd> 
    </catalog> 

cdcatalog_in.xsl содержание, как показано ниже:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="cd[country='IN']" name="IN" > 
<h4>Country: India</h4> 
</xsl:template> 
</xsl:stylesheet> 

cdcatalog_usa.xsl содержание, как показано ниже:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="cd[country='USA']" name="USA" > 
<h4>Country: United States of America</h4> 
</xsl:template> 
</xsl:stylesheet> 

cdcatalog_uk.xsl содержание, как показано ниже:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="cd[country='UK']" name="UK" > 
<h4>Country: United Kingdom</h4> 
</xsl:template> 
</xsl:stylesheet> 

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

Title : Empire Burlesque 
Artist: Bob Dylan 
Country: United States of America 

Title : Hide your heart 
Artist: Bonnie Tyler 
Country: United Kingdom 

Title : Greatest Hits 
Artist: Dolly Parton 
Country: United States of America 

Title : Still got the blues 
Artist: Gary Moore 
Country: India 

Ge чал ниже выход, который является неправильным

My CD Collection 

Country: United States of America 2 

Country: United Kingdom 

Country: United States of America 2 

Country: India 

Заранее спасибо. Srini

ответ

1

У вас есть возможность изменить ВКЛЮЧЕНЫ XSLT-файлы? Если это так, вы можете изменить их в соответствии с country вместо cd. Например, cdcatalog_in.XSL файл будет выглядеть следующим образом:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="cd/country[.='IN']"> 
    <h4>Country: India</h4> 
    </xsl:template> 
</xsl:stylesheet> 

Затем в основном файле XSLT, шаблон соответствия cd будет выглядеть следующим образом

<xsl:template match="cd"> 
<p> 
    <xsl:apply-templates select="country"/> 
    <xsl:apply-templates select="title"/> 
    <xsl:apply-templates select="artist"/> 
</p> 
</xsl:template> 

Можно даже добавить соответствие шаблона просто соответствие country в основной XSLT тоже, чтобы захватить "неизвестные" случаи

<xsl:template match="country"> 
    <h4>Country: UNKOWN</h4> 
</xsl:template> 
+0

Хорошо обрабатывать неизвестный случай страны – Rao

+0

Вместо того, чтобы показывать 'UNKNOWN', когда отсутствует соответствующий шаблон, возможно, может отображаться один и тот же код страны? – Rao

+0

Это решение работает нормально. Также мы все еще находимся в стадии разработки, поэтому мы можем вносить изменения в внешние шаблоны. – SriniRao

-1

Вместо использования нескольких файлов xsl для каждого счета все элементы cd могут быть выполнены в одном шаблоне xsl.

Вот измененный один стиль лист:cdcatalog.xsl

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

    <xsl:template match="/"> 
     <html> 
      <body> 
       <h2>My CD Collection</h2> 
       <xsl:apply-templates /> 
      </body> 
     </html> 
    </xsl:template> 

    <xsl:template match="cd"> 
     <p> 
      Title: <span style="color:#ff0000"> 
      <xsl:value-of select="./title"/></span><br/> 
      Artist: <span style="color:#00ff00"> 
      <xsl:value-of select="./artist"/></span><br/> 
      Country: <span style="color:#00ff11"> 
      <xsl:choose> 
       <xsl:when test="./country = 'IN'"> 
        India 
       </xsl:when> 
       <xsl:when test="./country = 'UK'"> 
        United Kingdom 
       </xsl:when> 
       <xsl:when test="./country = 'USA'"> 
        United States of America 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:value-of select="./country"/> 
       </xsl:otherwise> 
      </xsl:choose> 
      </span><br/> 
     </p> 
    </xsl:template> 

</xsl:stylesheet> 

А вот выход:

enter image description here

Надеется, что это работает для ваших потребностей.

+0

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

+0

Благодарим вас за ввод @MichaelKay. Он не собирался отказываться от трудностей, просто не мог понять, почему многие стили используются. Реализовавшись после публикации моего ответа о том, что несколько файлов могут иметь гибкость, чтобы расширяться, когда вводится новая страна, и работает с изменением так же, как и пользователь. В то время как я нашел ваш ответ. Рад узнать и оценить ваши отзывы. И спасибо за «режим», о котором я не знал. – Rao

1

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

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="cd[country='IN']" mode="country-name"> 
    <h4>Country: India</h4> 
    </xsl:template> 
</xsl:stylesheet> 

и изменить правила общего шаблона для:

<xsl:template match="cd"> 
    <xsl:apply-templates select="." mode="country-name"/> 
    <p> 
    <xsl:apply-templates select="title"/> 
    <xsl:apply-templates select="artist"/> 
    </p> 
</xsl:template> 
+0

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

2

Проблемные 0: у вас есть два шаблона, соответствующие одному и тому же узлу, и вам нужно применять оба.

Решение: Вместо включая внешних таблиц стилей, импорт их. Затем используйте xsl:apply-imports в локальном шаблоне, чтобы применить импортированный.

Не требуется модификация внешних стилей.

XSLT 1,0

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

<xsl:import href="cdcatalog_in.xsl"/> 
<xsl:import href="cdcatalog_usa.xsl"/> 
<xsl:import href="cdcatalog_uk.xsl"/> 

<xsl:template match="/"> 
    <html> 
     <body> 
      <h2>My CD Collection</h2> 
      <xsl:apply-templates/> 
     </body> 
    </html> 
</xsl:template> 

<xsl:template match="cd"> 
    <p> 
     <xsl:apply-imports /> 
     <xsl:apply-templates select="title"/> 
     <xsl:apply-templates select="artist"/> 
    </p> 
</xsl:template> 

<xsl:template match="title"> 
    Title: <span style="color:#ff0000"> 
    <xsl:value-of select="."/></span> 
    <br /> 
    </xsl:template> 

<xsl:template match="artist"> 
    Artist: <span style="color:#00ff00"> 
    <xsl:value-of select="."/></span> 
    <br /> 
</xsl:template> 

</xsl:stylesheet> 

Alernatively, вы могли бы использовать режимы - но по-прежнему без изменения внешних таблиц стилей:

XSLT 1.0

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

<xsl:include href="cdcatalog_in.xsl"/> 
<xsl:include href="cdcatalog_usa.xsl"/> 
<xsl:include href="cdcatalog_uk.xsl"/> 

<xsl:template match="/"> 
    <html> 
     <body> 
      <h2>My CD Collection</h2> 
      <xsl:apply-templates mode="first"/> 
     </body> 
    </html> 
</xsl:template> 

<xsl:template match="cd" mode="first" > 
    <p> 
     <xsl:apply-templates select="." /> 
     <xsl:apply-templates select="title"/> 
     <xsl:apply-templates select="artist"/> 
    </p> 
</xsl:template> 

<xsl:template match="title"> 
    Title: <span style="color:#ff0000"> 
    <xsl:value-of select="."/></span> 
    <br /> 
    </xsl:template> 

<xsl:template match="artist"> 
    Artist: <span style="color:#00ff00"> 
    <xsl:value-of select="."/></span> 
    <br /> 
</xsl:template> 

</xsl:stylesheet> 
+0

Это решение работает. будет ли какая-либо проблема с производительностью bcz apply-templates select = "." поскольку мы не рассматриваем точный шаблон. Но все равно спасибо. – SriniRao

+0

@SriniRao Я не уверен, что вы подразумеваете под словом «* не адресующий точный шаблон». Применение шаблонов к текущему узлу ничем не отличается от применения шаблонов к любому другому узлу/с. Если будут проблемы с производительностью, они будут гораздо чаще вызваны наличием нескольких файлов, по одному для каждой страны, чем что-либо еще. –

+0

Вместо apply-templates select = "." Есть ли возможность применить шаблон-шаблон select = "name". Так что система будет напрямую вытаскивать этот шаблон. – SriniRao

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