Я новичок в xslt. Я хочу преобразовать приведенный ниже ввод в вывод. Я хочу сгруппировать элементы h1 и h2, создать атрибут и добавить данные между двумя тегами h1 или h2 в качестве значения дочернего тега. Пожалуйста помоги. Спасибо.

Input.xml

<ATTRIBUTE-VALUE>
    <THE-VALUE>
        <div xmlns="http://www.w3.org/1999/xhtml">
            <h1 dir="ltr" id="_1536217498885">Main Description</h1>
            <p>Line1 The main description text goes here.</p>
            <p>Line2 The main description text goes here.</p>
            <h1 dir="ltr" id="_1536217498886">Steps</h1>
            <h2 dir="ltr" id="_1536217498886">Section Name One</h2>
            <p>Line1 The steps text goes here.</p>
            <ul>Line2 The section description text goes here.</ul>
            <h2 dir="ltr" id="_1536217498886">Section Name Two</h2>
            <p>Line1 The key consideration text goes here.</p>
            <ul><li>Line2 The key consideration text goes here.</li></ul>
            <h1 dir="ltr" id="_1536217498887">Skills</h1>
            <p>Line1 The Skills text goes here.</p>
            <p>Line2 The Skills text goes here.</p>
            <p>Line3 The Skills text goes here.</p>
            <h1 dir="ltr" id="_1536217498888">Synonyms</h1>
            <p>The Synonyms text goes here.</p>
        </div>
    </THE-VALUE>
</ATTRIBUTE-VALUE>

Output.xml

<MainDescription>
    <![CDATA[
        <p>Line1 The main description text goes here.</p>
        <p>Line2 The main description text goes here.</p>
    ]]>
</MainDescription>
<Section name="Section Name One">
    <Description>
        <p>Line1 The section text goes here.</p>
        <p>Line2 The description text goes here.</p>
    </Description>
</Section>
<Section name="Section Name Two">
    <Description>
        <p>Line1 The description text goes here.</p>
        <ul><li>Line2 The description text goes here.</li></ul>
    </Description>
</Section>
<Skills>
    <p>Line1 The Skills text goes here.</p>
    <p>Line2 The Skills text goes here.</p>
    <p>Line3 The Skills text goes here.</p>
</Skills>
<Synonyms>
    <p>The Synonyms text goes here.</p>
</Synonyms>

Я использовал ниже xsl для группировки тегов, но я не могу получить то, что требуется для output.xml. Если я применяю один и тот же шаблон к h1 и h2, я получаю результаты только для h1 или h2 с xsl ниже.

Xsl файл:

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xhtml="http://www.w3.org/1999/xhtml"
    xmlns:exsl="http://exslt.org/common"
    exclude-result-prefixes="xhtml exsl"
    version="1.0">

  <xsl:import href="http://lenzconsulting.com/xml-to-string/xml-to-string.xsl"/>

  <xsl:output method="xml" indent="yes"
    cdata-section-elements="MainDescription KeyConsideration"/>
  <xsl:strip-space elements="*"/>

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

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

  <xsl:key name="h1-group" match="xhtml:div/*[not(self::xhtml:h1)]" use="generate-id(preceding-sibling::xhtml:h1[1])"/>

  <xsl:template match="xhtml:div[xhtml:h1]">
      <xsl:apply-templates select="xhtml:h1"/>
  </xsl:template>

  <xsl:template match="xhtml:h1">
      <xsl:element name="{translate(., ' ', '')}">
          <xsl:variable name="rtf-with-xhtml-ns-stripped">
              <xsl:apply-templates select="key('h1-group', generate-id())"/>
          </xsl:variable>
          <xsl:apply-templates select="exsl:node-set($rtf-with-xhtml-ns-stripped)/node()" mode="xml-to-string"/>
      </xsl:element>
  </xsl:template>

  <xsl:template match="xhtml:p">
      <p>
          <xsl:apply-templates/>
      </p>
  </xsl:template>

</xsl:stylesheet>
0
Vishal Sharnagat 5 Ноя 2018 в 07:19

1 ответ

Лучший ответ

Я думаю, вам нужно определить второй ключ для группировки h2

<xsl:key name="h2-group" match="xhtml:div/*[not(self::xhtml:h2)]" use="generate-id(preceding-sibling::xhtml:h2[1])"/>

И затем есть второй шаблон, который соответствует h1 элементам, которые содержат h2 элементов в группе.

<xsl:template match="xhtml:h1[key('h1-group', generate-id())[self::xhtml:h2]]">
  <xsl:apply-templates select="key('h1-group', generate-id())[self::xhtml:h2]" />
</xsl:template>  

И в соответствии с шаблоном h2 вы должны выполнить группировку

<xsl:template match="xhtml:h2">
  <xsl:variable name="h1Group" select="key('h1-group', generate-id(preceding-sibling::xhtml:h1[1]))" />
  <Section name="{.}">
    <Description>
      <xsl:apply-templates select="key('h2-group', generate-id())[count(. | $h1Group) = count($h1Group)]"/>
   </Description>
  </Section>
</xsl:template>

Использование count здесь должно гарантировать, что вы выбираете только элементы, следующие за h2, которые находятся в текущей группе h1.

Попробуйте это XSLT

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xhtml="http://www.w3.org/1999/xhtml"
    xmlns:exsl="http://exslt.org/common"
    exclude-result-prefixes="xhtml exsl"
    version="1.0">

  <xsl:import href="http://lenzconsulting.com/xml-to-string/xml-to-string.xsl"/>

  <xsl:output method="xml" indent="yes" cdata-section-elements="MainDescription KeyConsideration"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="h1-group" match="xhtml:div/*[not(self::xhtml:h1)]" use="generate-id(preceding-sibling::xhtml:h1[1])"/>
  <xsl:key name="h2-group" match="xhtml:div/*[not(self::xhtml:h2)]" use="generate-id(preceding-sibling::xhtml:h2[1])"/>

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

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

  <xsl:template match="xhtml:div[xhtml:h1]">
      <xsl:apply-templates select="xhtml:h1"/>
  </xsl:template>

  <xsl:template match="xhtml:h1">
      <xsl:element name="{translate(., ' ', '')}">
          <xsl:choose>
            <xsl:when test=". = 'Main Description'">
              <xsl:variable name="rtf-with-xhtml-ns-stripped">
                <xsl:apply-templates select="key('h1-group', generate-id())"/>
              </xsl:variable>
              <xsl:apply-templates select="exsl:node-set($rtf-with-xhtml-ns-stripped)/node()" mode="xml-to-string"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:apply-templates select="key('h1-group', generate-id())"/>
            </xsl:otherwise>
          </xsl:choose>
      </xsl:element>
  </xsl:template>

  <xsl:template match="xhtml:h1[key('h1-group', generate-id())[self::xhtml:h2]]">
    <xsl:apply-templates select="key('h1-group', generate-id())[self::xhtml:h2]" />
  </xsl:template>  

  <xsl:template match="xhtml:h2">
    <xsl:variable name="h1Group" select="key('h1-group', generate-id(preceding-sibling::xhtml:h1[1]))" />
    <Section name="{.}">
      <Description>
        <xsl:apply-templates select="key('h2-group', generate-id())[count(. | $h1Group) = count($h1Group)]"/>
      </Description>
    </Section>
  </xsl:template>

  <xsl:template match="xhtml:p|xhtml:ul|xhtml:li">
      <xsl:element name="{local-name()}">
          <xsl:apply-templates/>
      </xsl:element>
  </xsl:template>
</xsl:stylesheet>
2
Tim C 5 Ноя 2018 в 09:26