Узлы слияния XSLT - PullRequest
       3

Узлы слияния XSLT

0 голосов
/ 09 сентября 2018

ТАК У меня грязный файл xhtml, который я хотел бы преобразовать в xml. Это лексикон с определенным количеством тегов 'p', и я хотел разобраться с ними. Вот файл xhtml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta content="2018-06-29T10:12:48Z" name="dcterms.created" />
        <meta content="2018-06-29T10:12:48Z" name="dcterms.modified" />
    </head>
    <body>
        <p><b>Aesthetik</b></p>
        <p>text about aesthetics.</p>
        <p><b>Expl: </b>explanation about aesthetics</p>
        <p><b>BegrG: </b>origin of the term</p>
        <p>more origin of the term</p>
        <p><b>Allegorese</b></p>
        <p>text about Allegorese</p>
        <p><b>Expl: </b>explanation about Allegorese</p>
        <p><b>BegrG: </b>origin of Allegorese</p>
    </body>
</html>

Файл XSLT выглядит следующим образом (есть несколько дополнительных строк для других тегов, которые здесь не включены):

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

<xsl:template match="head"/>

<xsl:template match="text()">
    <xsl:value-of select="normalize-space()"/>
</xsl:template>

<xsl:template match="body">
    <lexica>
        <xsl:apply-templates/>      <!-- create root node lexica -->
    </lexica>
</xsl:template>

<xsl:template match="p">
    <p>
        <xsl:apply-templates/> <!-- copy same tags for better visuality -->
    </p>
</xsl:template>

<xsl:template match="p[b[contains(., 'BegrG')]]">
    <BegrG>
        <xsl:apply-templates/>  <!-- create specific nodes with origin explanation of the word -->
    </BegrG>
</xsl:template>

<xsl:template match="p[b[contains(., 'Expl')]]">
    <Expl>
        <xsl:apply-templates/>  <!-- node with explanation of the word --> 
    </Expl>
</xsl:template>


<xsl:template
    match="
    p[b[not(self::*[contains(., 'Expl')]or
    self::*[contains(., 'BegrG')])]]">  <!-- any other b nodes which are left are lexical items -->
    <Artikel>
        <xsl:apply-templates/>
    </Artikel>
</xsl:template>

В конце мой XML-файл выглядит так:

    <lexica>
    <Artikel>Aesthetik</Artikel>
    <p>text about aesthetics.</p>
    <Expl>Expl:explanation about aesthetics</Expl>
    <BegrG>BegrG:origin of the term</BegrG>
    <p>more origin of the term</p>
    <Artikel>Allegorese</Artikel>
    <p>text about Allegorese</p>
    <Expl>Expl:explanation about Allegorese</Expl>
    <BegrG>BegrG:origin of Allegorese</BegrG>
</lexica>

Который выглядит лучше, но все равно не будет работать, поскольку он недостаточно структурирован. Например, термины не сгруппированы, и некоторые теги 'p' должны быть объединены с их предыдущим братом. Это должно выглядеть так:

<lexica>
 <item>
  <Artikel>Aesthetik</Artikel>
  <short>text about aesthetics.</short>
  <Expl>Expl:explanation about aesthetics</Expl>
  <BegrG>BegrG:origin of the term. more origin of the term.</BegrG>
 </item>

 <item>
  <Artikel>Allegorese</Artikel>
  <short>text about Allegorese</short>
  <Expl>Expl:explanation about Allegorese</Expl>
  <BegrG>BegrG:origin of Allegorese</BegrG>
 </item>
</lexica>

Я подхожу к этому неправильно или как я должен сгруппировать теги p к их родному брату, у которого есть b-child? И как мне отделить элементы термина друг от друга и заставить его распознавать, когда должен произойти тег закрытия?

(извините за мой плохой английский)

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

1 Ответ

0 голосов
/ 09 сентября 2018

XSLT 2/3 имеет for-each-group group-starting-with (https://www.w3.org/TR/xslt20/#xsl-for-each-group), поэтому вы можете реализовать создание item элементов с

  <xsl:template match="body">
      <lexica>
          <xsl:for-each-group select="*" group-starting-with="p[b[not(matches(., '^(Expl|BegrG):'))]]">
              <item>
                  <xsl:apply-templates select="current-group()"/>
              </item>
          </xsl:for-each-group>
      </lexica>
  </xsl:template>

Я думаю, что пример на https://xsltfiddle.liberty -development.net / bFDb2CG .

Пока я не уверен, что определяет слияние некоторых p элементов в результат BegrG, возможно, вложенную группировку с

  <xsl:template match="body">
      <lexica>
          <xsl:for-each-group select="*" group-starting-with="p[b[not(matches(., '^(Expl|BegrG):'))]]">
              <item>
                  <xsl:for-each-group select="current-group()" group-starting-with="p[b[starts-with(., 'BegrG:')]]">
                      <xsl:choose>
                          <xsl:when test="self::p[b[starts-with(., 'BegrG:')]]">
                              <BegrG>
                                  <xsl:apply-templates select="current-group()/node()"/>
                              </BegrG>
                          </xsl:when>
                          <xsl:otherwise>
                              <xsl:apply-templates select="current-group()"/>
                          </xsl:otherwise>
                      </xsl:choose>
                  </xsl:for-each-group>
              </item>
          </xsl:for-each-group>
      </lexica>
  </xsl:template>

реализует следующее: https://xsltfiddle.liberty -development.net / bFDb2CG / 1

Что касается проблемы, поднятой в комментарии, вы можете добавить еще одно совпадение к group-starting-with:

  <xsl:template match="body">
      <lexica>
          <xsl:for-each-group select="*" group-starting-with="p[b[not(matches(., '^(Expl|BegrG):'))]]">
              <item>
                  <xsl:for-each-group select="current-group()" group-starting-with="p[b[starts-with(., 'Expl:')]] | p[b[starts-with(., 'BegrG:')]]">
                      <xsl:choose>
                        <xsl:when test="self::p[b[starts-with(., 'Expl:')]]">
                              <Expl>
                                  <xsl:apply-templates select="current-group()/node()"/>
                              </Expl>
                          </xsl:when>
                          <xsl:when test="self::p[b[starts-with(., 'BegrG:')]]">
                              <BegrG>
                                  <xsl:apply-templates select="current-group()/node()"/>
                              </BegrG>
                          </xsl:when>
                          <xsl:otherwise>
                              <xsl:apply-templates select="current-group()"/>
                          </xsl:otherwise>
                      </xsl:choose>
                  </xsl:for-each-group>
              </item>
          </xsl:for-each-group>
      </lexica>
  </xsl:template>

https://xsltfiddle.liberty -development.net / bFDb2CG / 2

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