Nummerierung von verschahtelten Überschriften
Alex
- xml
Hallo zusammen,
ich möchte gerne mittels XSL, Überschriften die in einem XML Dokument vorhanden sind automatisch durchnummerieren.
Es sollen die Überschriften bis zur dritten Unterkategorie (1.1.1) nummeriert werden.
Die Überschriften heißen jeweils <headline>, können jedoch verschachtelt werden.
Bei meinen bisherigen Versuchen bin ich immer wieder an der Verschachtelung gescheiter.
Momentan schafft mein Entwurf folgende Struktur:
1
2
3
.1
.2
.2.1
.2.2
10 <- wird irtümlich um die Unterpunkte weitergezählt
Für eine Idee, wäre ich sehr dankbar.
Gruß Alex
Hier die zugehörige DTD und XSL:
DTD:
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT publication (articel+)>
<!ELEMENT articel (headline_top, author, keywords+, abstract, introduction, maintext+, summary, bibliography?, biography)>
<!ATTLIST articel
id ID #REQUIRED
>
<!ELEMENT headline_top (#PCDATA) >
<!ELEMENT headline (#PCDATA) >
<!ELEMENT author (author_titel?, author_surname, author_prename, author_adress)>
<!ELEMENT author_titel (#PCDATA) >
<!ELEMENT author_surname (#PCDATA) >
<!ELEMENT author_prename (#PCDATA) >
<!ELEMENT author_adress (author_adress_company?, author_adress_street, author_adress_city, author_adress_country, author_adress_email?, author_adress_www?)>
<!ELEMENT author_adress_company (#PCDATA) >
<!ELEMENT author_adress_street (#PCDATA) >
<!ELEMENT author_adress_city (#PCDATA) >
<!ELEMENT author_adress_country (#PCDATA) >
<!ELEMENT author_adress_email (#PCDATA) >
<!ELEMENT author_adress_www (#PCDATA) >
<!ATTLIST author_adress_www
ref CDATA #REQUIRED
>
<!ELEMENT keywords (headline, keywords_keywords+)>
<!ELEMENT keywords_keywords (keywords_keywords_element+) >
<!ELEMENT keywords_keywords_element (#PCDATA) >
<!ELEMENT abstract (headline, abstract_text) >
<!ELEMENT abstract_text (#PCDATA | abstract_text_link)* >
<!ELEMENT abstract_text_link (#PCDATA) >
<!ATTLIST abstract_text_link
bibliography_ref IDREF #REQUIRED
>
<!ELEMENT introduction (headline, introduction_text) >
<!ELEMENT introduction_text (#PCDATA | introduction_text_list | introduction_text_link)* >
<!ELEMENT introduction_text_list (introduction_text_list_element+) >
<!ELEMENT introduction_text_list_element (#PCDATA) >
<!ELEMENT introduction_text_link (#PCDATA)>
<!ATTLIST introduction_text_link
bibliography_ref IDREF #REQUIRED
>
<!ELEMENT maintext (headline, maintext_text) >
<!ELEMENT maintext_text (#PCDATA | maintext_text_list | maintext_text_code | maintext_text_code_extern | maintext_text_www | maintext_text_link | maintext)* >
<!ELEMENT maintext_text_list (maintext_text_list_element+) >
<!ELEMENT maintext_text_list_element (#PCDATA) >
<!ELEMENT maintext_text_code (#PCDATA) >
<!ELEMENT maintext_text_code_extern (#PCDATA) >
<!ELEMENT maintext_text_www (#PCDATA) >
<!ATTLIST maintext_text_www
ref CDATA #REQUIRED
>
<!ELEMENT maintext_text_link (#PCDATA)>
<!ATTLIST maintext_text_link
bibliography_ref IDREF #REQUIRED
>
<!ELEMENT summary (headline, summary_text) >
<!ELEMENT summary_text (#PCDATA | summary_text_list | summary_text_code | summary_text_www | summary_text_link)* >
<!ELEMENT summary_text_list (#PCDATA) >
<!ELEMENT summary_text_code (#PCDATA) >
<!ELEMENT summary_text_www (#PCDATA) >
<!ATTLIST summary_text_www
ref CDATA #REQUIRED
>
<!ELEMENT summary_text_link (#PCDATA) >
<!ATTLIST summary_text_link
bibliography_ref IDREF #REQUIRED
>
<!ELEMENT bibliography (headline, bibliography_content+) >
<!ELEMENT bibliography_content (bibliography_content_linkname, bibliography_content_name, bibliography_content_date)>
<!ELEMENT bibliography_content_linkname (#PCDATA) >
<!ELEMENT bibliography_content_name (#PCDATA) >
<!ELEMENT bibliography_content_date (#PCDATA) >
<!ATTLIST bibliography_content_linkname
bibliography_content_ref ID #REQUIRED
>
<!ELEMENT biography (headline, biography_author, biography_text) >
<!ELEMENT biography_author (#PCDATA) >
<!ELEMENT biography_text (#PCDATA) >
XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="publication">
<html>
<head>
<title>Titel</title>
<link rel="stylesheet" href="default.css" />
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="headline_top"><div id="headline_top"><xsl:apply-templates/></div></xsl:template>
<xsl:template match="headline">
<h1>
<xsl:number level="any" count="headline" format="1. " />
<xsl:apply-templates/>
</h1>
</xsl:template>
<xsl:template match="author_adress"></xsl:template>
<xsl:template match="keywords_keywords"><ul><xsl:apply-templates/> </ul></xsl:template>
<xsl:template match="keywords_keywords_element"><li><xsl:apply-templates/> </li></xsl:template>
<xsl:template match="abstract_text"><p><xsl:apply-templates/></p> </xsl:template>
<xsl:template match="abstract_text_link"><a href="#{@bibliography_ref}"><xsl:apply-templates/></a></xsl:template>
<xsl:template match="introduction_text"><p><xsl:apply-templates/></p> </xsl:template>
<xsl:template match="introduction_text_link"><a href="#{@bibliography_ref}"><xsl:apply-templates/></a></xsl:template>
<xsl:template match="introduction_text_list"><ul><xsl:apply-templates/> </ul></xsl:template>
<xsl:template match="introduction_text_list_element"><li><xsl:apply-templates/> </li></xsl:template>
<xsl:template match="/publication/articel/maintext/maintext_text/maintext/headline">
<h2>
<xsl:number level="multiple" count="headline|/publication/articel/maintext/maintext_text/maintext/headline" format="1.1 "/>
<xsl:apply-templates/>
</h2>
</xsl:template>
<xsl:template match="/publication/articel/maintext/maintext_text/maintext/maintext_text/maintext/headline">
<h3>
<xsl:number level="multiple" count="headline|/publication/articel/maintext/maintext_text/maintext/headline|/publication/articel/maintext/maintext_text/maintext/maintext_text/maintext" format="1.1.1 "/>
<xsl:apply-templates/>
</h3>
</xsl:template>
<xsl:template match="maintext_text"><p><xsl:apply-templates/></p> </xsl:template>
<xsl:template match="maintext_text_list"><ul><xsl:apply-templates/> </ul></xsl:template>
<xsl:template match="maintext_text_code"><span class="code"><xsl:apply-templates/></span></xsl:template>
<xsl:template match="maintext_text_code_extern"><div class="code_extern"><xsl:apply-templates/></div></xsl:template>
<xsl:template match="maintext_text_link"><a href="#{@bibliography_ref}"><xsl:apply-templates/></a></xsl:template>
<xsl:template match="maintext_text_www"><a href="{@ref}" target="_blank"><xsl:apply-templates/></a></xsl:template>
<xsl:template match="summary_text"><p><xsl:apply-templates/></p> </xsl:template>
<xsl:template match="summary_text_list"><ul><xsl:apply-templates/> </ul></xsl:template>
<xsl:template match="summary_text_code"><span class="code"><xsl:apply-templates/></span></xsl:template>
<xsl:template match="summary_text_link"><a href="#{@bibliography_ref}"><xsl:apply-templates/></a></xsl:template>
<xsl:template match="bibliography_content_linkname "><h3><a name="{@bibliography_content_ref}"><xsl:apply-templates/></a></h3></xsl:template>
<xsl:template match="bibliography_content_name"><xsl:apply-templates/></xsl:template>
<xsl:template match="bibliography_content_date"><xsl:apply-templates/></xsl:template>
<xsl:template match="biography_autho"><xsl:apply-templates/></xsl:template>
<xsl:template match="biography_text"><xsl:apply-templates/></xsl:template>
</xsl:stylesheet>
Hi,
sowas hab ich schonmal mit Perl komplett automatisiert, d.h.: Die Gliederung händisch erstellt und dann rekursiv durchlaufen, wobei je nach Tiefe die Ord.Nr. der headline zugeordnet wurde.
Hotte
Hilfe, mach dir das Leben doch nicht so schwer. Es wuerde doch einfach reichen (vorausgesetzt ich habe deine xml struktur verstanden:
<xsl:template match="headline">
<xsl:element name="{concat('h',count(ancestor::*[preceding-sibling::headline]) + 1)}">
<xsl:for-each select="ancestor::*[preceding-sibling::headline]">
<xsl:value-of select="count(preceding-sibling::headline)"/>
<xsl:text>.</xsl:text>
</xsl:for-each>
<xsl:value-of select="count(preceding-sibling::headline) + 1"/>
</xsl:element>
</xsl:template>
Vielen Dank für die Antworten.
Ich habe den Code von dir mal eingebaut. Die automatische Vergabe der Überschriften (h1, h2, h3) klappt ohne Probleme. Auch werden die Unterkapitel wie gewollt in die Ebenen eingeteilt (1.1.1) das einzige Problem ist, dass bei allen Überschriften immer nur die 1 erscheint. Aus irgend einem Grund zählt der Zähler nicht weiter...
Hättest du noch einen Tipp an was das liegen könnte?
Gruß und Danke Alex
Hallo,
kannst du mal einen Ausschnitt aus deiner xml geben, das DTD zu lesen ist muehsam? Die Ursache duerfte aber in der Anweisung count(preceding-sibling::headline) liegen.
Also kuerze einfach mal so weit die xml datei und poste ein fragment davon, hilft ungemein zum verstaendnis.
Hallo,
hier ein Auszug aus meiner xml Datei:
<introduction>
<headline>Introduction</headline>
<introduction_text>text...
</introduction_text>
</introduction>
<maintext>
<headline>Eine Ueberschrift</headline>
<maintext_text>
text
<maintext>
<headline>Eine Unterueberschrift</headline>
<maintext_text>
<maintext>
<headline>Eine UnterUnterueberschrift</headline>
<maintext_text>
text
</maintext_text>
</maintext>
<maintext>
<headline>Eine UnterUnterueberschrift</headline>
<maintext_text>
text
</maintext_text>
</maintext>
</maintext_text>
</maintext>
<maintext>
<headline>Eine Unterueberschrift</headline>
<maintext_text>
text
<maintext>
<headline>Eine UnterUnterueberschrift</headline>
<maintext_text>
text
´<maintext>
<headline>Eine UnterUnterueberschrift</headline>
<maintext_text>
text
</maintext_text>
</maintext>
</maintext_text>
</maintext>
</maintext_text>
</maintext>
</maintext_text>
</maintext>
Habe das ganze nicht ueberprueft, aber so koennte es funktionieren. Am besten du schaust dir auch noch mal die adressierung per xpath an, wird hier bei selfhtml.org ziemlich anschaulich dargestellt
<xsl:template match="headline">
<xsl:element name="{concat('h',count(ancestor::*[headline]))}">
<!-- durchlaufe alle headline auf vorgelagerten Stufen -->
<xsl:for-each select="parent::*/ancestor::*[headline]">
<!-- zaehle alle headline auf gleicher Stufe plus 1 -->
<xsl:value-of select="count(preceding-sibling::*/headline) + 1"/>
<xsl:text>.</xsl:text>
</xsl:for-each>
<!-- zaehle alle vorgelagerten headline auf gleicher Stufe plus 1 -->
<xsl:value-of select="count(parent::*/preceding-sibling::*[headline]) + 1"/>
<xsl:text> </xsl:text>
<!-- headline Textinhalt ausgeben -->
<xsl:value-of select="text()"/>
</xsl:element>
</xsl:template>
Gruss, H.
Funktioniert!
Vielen, Vielen Dank für Deine Hilfe!
Gruß Alex