Mareike Laue
Mareike Laue

Reputation: 41

XSLT 2.0 one element for different situations (@mode does not work)

I am completly new to XSLT (Iam working with oxygen, XSLT 2.0) I tried to find solutions online and in my book but cant figure it out.

I have the following situation: I have an XML (TEI) that has different 'term' elements in the paragraphs. I want to do different stuff with the terms but with @mode it doesnt work. 1. I want to give the terms a link 2. I want to match element 'lb/' -> element 'br/' when 'lb' is within 'term' (<term> tex <lb /> t </term>) 3. I want to make ´del` dissapear in my html when its within 'term' 4. If within 'term' is a seperator "-" I want to insert in my html 'br/'

an extract of my XML (text makes no sense):

<p>und <term>toxische <lb/>
    Quote</term> dabei eine Rolle. – text<term><del>t</del><add rend="overtyped">t</add><del>t</del><add type="overtyped">l</add></term>leicht teilen Sie mir einmal <lb/>
    freundlichst Ihre Ansicht mit.</p> 

for 4. I used this:

<xsl:template match="tei:term">

<xsl:variable name="linktext" select="text()"/>
<a href="https://de.wikipedia.org/wiki/{$linktext}" target="_blank"> 
    <xsl:for-each select="tokenize(.,'-')">
        <xsl:sequence select="."/>
        <xsl:if test="not(position() eq last())">-<br /></xsl:if>
    </xsl:for-each> 

  </a>

I tried to work with @modes for the other situations but it didnt work. Does anyone have an idea how I can encode this?

Thanks in advance!!

The result I want to have is the following html code:

<p> und <a href="href="https://de.wikipedia.org/wiki/toxischeQuote">toxische<br/>
Quote</a> dabei eine Rolle. - text<a      href="href="https://de.wikipedia.org/wiki/texttl">
texttl</a> leicht teilen Sie mir einmal <br/> freundlichst Ihre Ansicht mit. </p>

I want the content of 'del' to disappear.

Upvotes: 2

Views: 112

Answers (2)

Martin Honnen
Martin Honnen

Reputation: 167696

<xsl:template match="tei:term">
  <a href="https://de.wikipedia.org/wiki/{.}" target="_blank">
    <xsl:apply-templates/>
  </a>
</xsl:template>

<xsl:template match="tei:term/tei:lb">
  <br/>
</xsl:template>

<xsl:template match="tei:term/tei:del"/>

<xsl:template match="tei:term//text()">
<xsl:for-each select="tokenize(.,'-')">
        <xsl:sequence select="."/>
        <xsl:if test="not(position() eq last())">-<br /></xsl:if>
    </xsl:for-each>
</xsl:template>

Upvotes: 1

Tomalak
Tomalak

Reputation: 338326

I want to give the terms a link

That's:

<xsl:template match="tei:term">
  <xsl:variable name="linktext" select="
    normalize-space(string-join(.//text()[not(parent::del)], ''))
  " />  <!-- ... or something like that -->

  <a href="http://de.wikipedia.org/w/index.php?search={encode-for-uri($linktext)}" target="_blank"> 
    <xsl:apply-templates select="node()" />
  </a>
</xsl:template>

I want to match element <lb/> -> <br/> when <lb/> is within <term>

That's:

<xsl:template match="tei:term/tei:lb">
  <br />
</xsl:template>

I want to make <del> dissappear in my HTML when its within <term>

That's

<xsl:template match="tei:term/tei:del" />

And, very likely you want this, too:

<xsl:template match="tei:term/tei:add">
  <xsl:value-of select="." />
</xsl:template>

If within <term> is a seperator "-" I want to insert in my html <br/>

That's

<xsl:template match="tei:term/text()">
  <xsl:for-each select="tokenize(., '-')">
    <xsl:sequence select="." />
    <xsl:if test="not(position() = last())">-<br /></xsl:if>
  </xsl:for-each> 
</xsl:template>

Note that

  • this approach processes child nodes of <term> in their order of appearance through <xsl:apply-templates>. Then it's easy to implement your rules by specific templates.
  • You only want to tokenize individual text nodes, not the entire string contents of <term>
  • You should (i.e., must) use the encode-for-uri() function when building URLs.

Upvotes: 1

Related Questions