XSLT - как разобрать xml с рекурсивными элементами в Eclipse toc.xml? - PullRequest
1 голос
/ 12 октября 2009

У меня есть следующий XML:

<HTML>
  <HEAD>
    <META name="GENERATOR" content="Microsoft HTML Help Workshop 4.1" />
    <!-- Sitemap 1.0 -->
  </HEAD>
  <BODY>
    <OBJECT type="text/site properties">
      <param name="FrameName" value="contents" />
    </OBJECT>
    <UL>
      <LI>
        <OBJECT type="text/sitemap">
          <param name="Name" value="Title1" />
          <param name="Local" value="Ref1" />
        </OBJECT>
        <UL>
          <LI>
            <OBJECT type="text/sitemap">
              <param name="Name" value="Title 2" />
              <param name="Local" value="Ref2" />
            </OBJECT>
            <UL>
              <LI>
                <OBJECT type="text/sitemap">
                  <param name="Name" value="Title3" />
                  <param name="Local" value="Ref3" />
                </OBJECT>
              </LI>
              <LI>
                <OBJECT type="text/sitemap">
                  <param name="Name" value="Title4" />
                  <param name="Local" value="Ref4" />
                </OBJECT>
              </LI>
            </UL>
          </LI>
          <LI>
            <OBJECT type="text/sitemap">
              <param name="Name" value="Title5" />
              <param name="Local" value="Ref5" />
            </OBJECT>
          </LI>
        </UL>
      </LI>
      <LI>
        <OBJECT type="text/sitemap">
          <param name="Name" value="Title6" />
          <param name="Local" value="Ref6" />
        </OBJECT>
      </LI>
    </UL>
  </BODY>
</HTML>

Мне нужно преобразовать его в файл формата «Eclipse Help» toc.xml, например:

<toc label="Sample Table of Contents">
  <topic label="Title1"  href="Ref1"> 
    <topic label="Title2" href="Ref2">
      <topic label="Title3" href="Ref3"/>
        <topic label="Title4" href="Ref4"/>
      </topic> 
      <topic label="Title5" href="Ref5">
    </topic> 
  </topic>
  <topic label="Title6" href="Ref6"/>
</toc>

Я попытался создать следующий XSLT, который не работал:

<?xml version="1.0" encoding="utf-8"?>
<?altova_samplexml D:\Documents and Settings\oshecht\Desktop\XSL\Copy of toc.xml?>
<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />

  <xsl:template match="/">
    <toc>
      <xsl:apply-templates select="//LI" />
    </toc>
  </xsl:template>

  <xsl:template match="//LI">
    <topic>
      <xsl:apply-templates select="OBJECT/param" mode="val" />
      <xsl:apply-templates select="OBJECT/param" mode="ref" />
      <xsl:apply-templates select="/UL/LI" />
      <!--xsl:apply-templates select="//UL//LI"  mode="subelement" /-->
    </topic>
  </xsl:template>

  <xsl:template match="OBJECT/param" mode="val">
    <xsl:if test="@name = 'Name'">
      <xsl:attribute name="label">
        <xsl:value-of select="@value" />
      </xsl:attribute>
    </xsl:if>
  </xsl:template>

  <xsl:template match="OBJECT/param" mode="ref">
    <xsl:if test="@name = 'Local'">
      <xsl:attribute name="href">
        <xsl:value-of select="@value" />
      </xsl:attribute>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

Не могли бы вы посоветовать?

Спасибо:)

Ответы [ 2 ]

3 голосов
/ 12 октября 2009

Я думаю, что следующее делает то, что вы хотите:

<xsl:template match="BODY">
    <toc label="Sample Table of Contents">
        <xsl:apply-templates select="UL/LI/OBJECT"/>
  </toc>
</xsl:template>

<xsl:template match="OBJECT">
  <topic label="{param[@name='Name']/@value}" href="{param[@name='Local']/@value}">
    <xsl:apply-templates select="following-sibling::UL/LI/OBJECT"/>
  </topic>
</xsl:template>
1 голос
/ 12 октября 2009

Ваша главная проблема в этой строке:

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

Это создает список всех <LI> элементов на входе и, таким образом, создает плоский выходной список. Вы можете использовать встроенную рекурсию и «двигаться в потоке», например:

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

  <xsl:template match="BODY">
    <toc>
      <xsl:apply-templates select="OBJECT" />
      <xsl:apply-templates select="UL" />
    </toc>
  </xsl:template>

  <xsl:template match="UL">
    <xsl:apply-templates select="LI" />
  </xsl:template>

  <xsl:template match="LI">
    <topic>
      <xsl:apply-templates select="OBJECT" />
      <xsl:apply-templates select="UL" />
    </topic>
  </xsl:template>

  <xsl:template match="OBJECT">
    <xsl:apply-templates select="param" />
  </xsl:template>

  <xsl:template match="OBJECT/param">
    <xsl:variable name="attrName">
      <xsl:choose>
        <xsl:when test="@name = 'FrameName'">label</xsl:when>
        <xsl:when test="@name = 'Name'">label</xsl:when>
        <xsl:when test="@name = 'Local'">href</xsl:when>
      </xsl:choose>
    </xsl:variable>
    <xsl:if test="$attrName != ''">
      <xsl:attribute name="{$attrName}">
        <xsl:value-of select="@value" />
      </xsl:attribute>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

Полученная продукция:

<?xml version="1.0" encoding="utf-8"?>
<toc label="contents">
  <topic label="Title1" href="Ref1">
    <topic label="Title 2" href="Ref2">
      <topic label="Title3" href="Ref3"></topic>
      <topic label="Title4" href="Ref4"></topic>
    </topic>
    <topic label="Title5" href="Ref5"></topic>
  </topic>
  <topic label="Title6" href="Ref6"></topic>
</toc>

Обратите внимание, что я заменил ваши шаблоны "mode" на <xsl:choose>. Все остальное довольно очевидно, я думаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...