Преобразуйте XML с помощью XSL, а затем отформатируйте вывод как HTML

Мне нужно отформатировать ввод XML с помощью XSL, чтобы получить более удобную структуру. В качестве следующего шага обработки я хочу преобразовать его в HTML. Предположим, у меня есть следующие входные данные: (0)

<list>
<item item-id="1" second-item-id="1" third-item-id="1"/>
<item item-id="1" second-item-id="1" third-item-id="2"/>
<item item-id="1" second-item-id="2" third-item-id="1"/>
<item item-id="1" second-item-id="3" third-item-id="1"/>

<item item-id="2" second-item-id="1" third-item-id="1"/>
<item item-id="2" second-item-id="1" third-item-id="2"/>
<item item-id="2" second-item-id="1" third-item-id="3"/>
<item item-id="2" second-item-id="2" third-item-id="1"/>

<item item-id="3" second-item-id="1" third-item-id="1"/>
<item item-id="3" second-item-id="1" third-item-id="2"/>
<item item-id="3" second-item-id="1" third-item-id="3"/>
<item item-id="3" second-item-id="1" third-item-id="4"/>
</list>

и следующий шаблон XSL: (1)

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

  <xsl:output indent="yes"/>

  <xsl:key name="itemKey" match="item" use="@item-id"/>
  <xsl:key name="secondItemKey" match="item" use="concat(@item-id, '|', @second-item-id)"/>

  <xsl:template match="list">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates select="item[generate-id() = generate-id(key('itemKey', @item-id)[1])]"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="item">
    <item item-id="{@item-id}">
      <xsl:apply-templates select="key('itemKey', @item-id)[generate-id() = generate-id(key('secondItemKey', concat(@item-id, '|', @second-item-id))[1])]" mode="evt"/>
    </item>
  </xsl:template>

  <xsl:template match="item" mode="evt">
    <second-item second-item-id="{@second-item-id}">
      <xsl:apply-templates select="key('secondItemKey', concat(@item-id, '|', @second-item-id))" mode="bus"/>
    </second-item>
  </xsl:template>

  <xsl:template match="item" mode="bus">
    <third-item third-item-id="{@third-item-id}"/>
  </xsl:template>    

</xsl:stylesheet>

это дает мне довольно хороший XML: (2)

<?xml version="1.0"?>
<list>
    <item item-id="1">
        <second-item second-item-id="1">
            <third-item third-item-id="1"/>
            <third-item third-item-id="2"/>
        </second-item>
        <second-item second-item-id="2">
            <third-item third-item-id="1"/>
        </second-item>
        <second-item second-item-id="3">
            <third-item third-item-id="1"/>
        </second-item>
    </item>
    <item item-id="2">
        <second-item second-item-id="1">
            <third-item third-item-id="1"/>
            <third-item third-item-id="2"/>
            <third-item third-item-id="3"/>
        </second-item>
        <second-item second-item-id="2">
            <third-item third-item-id="1"/>
        </second-item>
    </item>
    <item item-id="3">
        <second-item second-item-id="1">
            <third-item third-item-id="1"/>
            <third-item third-item-id="2"/>
            <third-item third-item-id="3"/>
            <third-item third-item-id="4"/>
        </second-item>
    </item>
</list>

у меня есть другой XSL, который преобразует XML #2 в html:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes" method="html"/>
    <xsl:template match="list">
        <xsl:for-each select="item">
            <h2><xsl:value-of select="concat(local-name(),' ',@item-id)"/></h2>
            <ul>
                <xsl:for-each select="second-item">
                    <li><xsl:value-of select="concat(local-name(),' ',@second-item-id)"/></li>
                    <ul>
                        <xsl:for-each select="third-item">
                            <li><xsl:value-of select="concat(local-name(),' ',@third-item-id)"/></li>
                        </xsl:for-each>
                    </ul>
                </xsl:for-each>
            </ul>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Итак, вот вопрос: я хочу обработать входной xml с обоими шаблонами (или объединенными) за один шаг. Как мне это сделать?

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


person Grook    schedule 28.01.2013    source источник
comment
Какой процессор XSLT вы используете?   -  person JLRishe    schedule 28.01.2013
comment
Еще один хороший ресурс: stylusstudio.com/xsllist/200107/post10390.html.   -  person Pow-Ian    schedule 28.01.2013


Ответы (1)


Если вы довольны просто объединением их вместе, то это должно выполнять работу обоих одновременно:

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

  <xsl:output indent="yes"/>

  <xsl:key name="itemKey" match="item" use="@item-id"/>
  <xsl:key name="secondItemKey" match="item" use="concat(@item-id, '|', @second-item-id)"/>

  <xsl:template match="list">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates select="item[generate-id() = generate-id(key('itemKey', @item-id)[1])]"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="item">
    <h2>
      <xsl:value-of select="concat('item ', @item-id)"/>
    </h2>
    <ul>
      <xsl:apply-templates select="key('itemKey', @item-id)[generate-id() = generate-id(key('secondItemKey', concat(@item-id, '|', @second-item-id))[1])]" mode="evt"/>
    </ul>
  </xsl:template>

  <xsl:template match="item" mode="evt">
    <li>
      <xsl:value-of select="concat('second-item ', @second-item-id)"/>
    </li>
    <ul>
      <xsl:apply-templates select="key('secondItemKey', concat(@item-id, '|', @second-item-id))" mode="bus"/>
    </ul>
  </xsl:template>

  <xsl:template match="item" mode="bus">
    <li>
      <xsl:value-of select="concat('third-item ', @third-item-id)"/>
    </li>
  </xsl:template>

</xsl:stylesheet>

Существует достаточно простой способ включить их оба в один XSLT и запускать один за другим, но подход, который я имею в виду, потребует использования функции node-set(), которая, к сожалению, находится в другом пространстве имен для каждой реализации XSLT. Какой процессор XSLT вы используете?

person JLRishe    schedule 28.01.2013