
Angesichts dieses Codes, der XML kaum analysiert und als SXML (s-exp XML, auch bekannt als XML im Lisp-Stil oder XML mit Klammern) druckt:
\catcode`@=11
\let\@xp\expandafter
\def\@makeletter#1#2\@nil{\catcode`#1 \ifx\relax#2\relax\else\@makeletter#2\@nil\fi}
\def\@gobble#1 {}
\def\@nil{}
\catcode`<13
\catcode`>12
\def\@split #1#2 #3\@nil{#1{#2} \ifx\relax#3\relax\else\@split#1#3\@nil\fi}
\def\defelt#1{\def<#1##1>##2</#1>{ (#1 {\ifx\relax##1\relax\else \@xp\@split\@xp\@key\@gobble ##1 \@nil\fi} ##2) }}
\defelt{div}
\defelt{span}
\catcode`?6
\catcode`#11
\def\@key?1=?2{ {\tt #:?1} ?2}
\def\@key?1{ {\tt #:?1}}
\catcode`^^J=10 \catcode`?=11 \catcode`^=11 \catcode`_=11 \catcode`~=11 \catcode`{=11 \catcode`}=11 %\catcode`\=11
%\@makeletter?^_~{}%\@nil
<span>first<span foo bar=yes>second</span>three</span>
\eject
\end
Das erste Problem besteht darin, dass die Neudefinition \
von Catcode nicht funktioniert, da danach \<string>
immer noch der Fehler „undefinierte Steuersequenz“ auftritt. Das zweite (weniger wichtige) besteht darin, dass ich keine Schleife schreiben kann, um Catcodes wiederholt neu zu definieren. Und das dritte und wichtigste Problem besteht darin, dass ich keine Schleife schreiben kann, um Catcodes wiederholt neu zu definieren.
Warum unterstützt TeX keine Makroüberladung? Ich meine, wie Sie sehen, habe ich es mit gemacht \xattr
, aber noch schlimmer ist das , \defelt
das „<“ mit mehreren Sachen zwischen seinen Argumenten neu definiert. Das Problem ist, entweder finde ich einen Weg, die Steuersequenz „<“ alle XML-Tags emulieren zu lassen, oder ich mache „<“ zum Catcode 0 und das bedeutet dann, dass ich Zugriff auf aaaalle TeX-Steuersequenzen innerhalb des XML gewähren muss, das ich analysieren möchte (was hässlich ist): Wie kann ich das dann machen?
Gibt es eine andere Lösung, als nur den Befehl < zu definieren und dann den nachfolgenden Text rekursiv zu lesen, ohne die Analysefunktionen von TeX zu nutzen?
Antwort1
Nehmen wir folgendes Eingabebeispiel an:
<?xml version="1.0" encoding="utf8"?>
<cenik>
<nazev>Počítačové komponenty</nazev>
<platnost od="1.1.2000" do="31.3.2000"/>
<dodavatel>
<nazev>První hardwarová, s.r.o.</nazev>
<adresa>
<ulice>Průmyslová 12</ulice>
<mesto>Praha 10</mesto>
<psc>100 000</psc>
<email>[email protected]</email>
</adresa>
</dodavatel>
<nabidka>
<produkt kategorie="polohovací zařízení" kod="pxbd-21">
<nazev>Hyperoptická <em>digitální</em> myš</nazev>
<cena mena="CZK">368.30</cena>
</produkt>
<produkt kategorie="pevné disky" kod="sbhd-99">
<nazev>Soft-slow disc < 19,3 GB</nazev>
<cena mena="CZK">8500</cena>
</produkt>
<produkt kategorie="polohovací zařízení" kod="pxbd-13">
<nazev>Tlakový tablet</nazev>
<cena mena="CZK">5635.20</cena>
</produkt>
</nabidka>
</cenik>
Versuchen Sie dann, es beispielsweise mit meinem Makro \xmlprep {input} {output}
mithilfe eines Befehls zu verarbeiten .pdftex thisfile
\newwrite\xmloutfile
\def\xmlprep#1#2{% #1=input file, #2=output file
\ifx\relax#2\relax \chardef\xmloutfile=16 \else
\immediate\openout\xmloutfile=#2 \fi
\begingroup \everypar={\setbox0=\lastbox\par \xscan}\input#1 \endgroup
\immediate\closeout\xmloutfile
}
\long\def\xscan#1<{\ifx\xscan#1\xscan \else
\toks0={#1}\xprint{\the\toks0\npercent}\fi\xtag}
\def\nob#1{}\edef\nob{\expandafter\nob\string\{}
\def\ncb#1{}\edef\ncb{\expandafter\ncb\string\}}
\def\npercent#1{}\edef\npercent{\expandafter\npercent\string\%}
\def\xprint#1{\immediate\write\xmloutfile{\xindent#1}}
\def\xindent{}
\def\xtag#1#2>{\ifx#1?\xtagD#2>\else\ifx#1/\xtagC#2>\else\xtagE#1#2>/>\end\fi\fi}
\def\xtagE#1/>#2\end{\ifx>#2>\let\tmp=n\xtagA#1 \end\else \let\tmp=/\xtagA#1> \end\fi}
\def\xtagA#1 #2\end{\def\currargs{}\ifx>#2>\xtagB#1\else \xargsB#2\xtagB#1>\fi}
\def\xtagB#1>{\bgroup\def\currtag{#1}%
\ifx\tmp/\xprint{\string\XML#1{\currargs}{}}\egroup\else
\xprint{\string\XML#1{\currargs}\nob\npercent}%
\edef\xindent{\xindent\space\space}\fi}
\def\xtagD#1?>{\xprint{\string\META{#1}}}
\def\xargsB#1>{\def\currargs{#1}}
\def\xtagC#1>{\def\tmp{#1}\ifx\tmp\currtag\else
\message{WARNING: <\currtag>...</#1> doesn't match}\fi
\egroup\xprint{\ncb}%
}
\xmlprep {test.xml} {test.out}
\end
Sie erhalten die folgende Ausgabetest.out
\META{xml version="1.0" encoding="utf8"}
\XMLcenik{}{%
\XMLnazev{}{%
Počítačové komponenty%
}
\XMLplatnost{od="1.1.2000" do="31.3.2000"}{}
\XMLdodavatel{}{%
\XMLnazev{}{%
První hardwarová, s.r.o.%
}
\XMLadresa{}{%
\XMLulice{}{%
Průmyslová 12%
}
\XMLmesto{}{%
Praha 10%
}
\XMLpsc{}{%
100 000%
}
\XMLemail{}{%
[email protected]%
}
}
}
\XMLnabidka{}{%
\XMLprodukt{kategorie="polohovací zařízení" kod="pxbd-21"}{%
\XMLnazev{}{%
Hyperoptická %
\XMLem{}{%
digitální%
}
myš%
}
\XMLcena{mena="CZK"}{%
368.30%
}
}
\XMLprodukt{kategorie="pevné disky" kod="sbhd-99"}{%
\XMLnazev{}{%
Soft-slow disc < 19,3 GB%
}
\XMLcena{mena="CZK"}{%
8500%
}
}
\XMLprodukt{kategorie="polohovací zařízení" kod="pxbd-13"}{%
\XMLnazev{}{%
Tlakový tablet%
}
\XMLcena{mena="CZK"}{%
5635.20%
}
}
}
}
Dies ist ein TeX-freundliches Format. Sie können einfach verwendete Tags usw. sowie Makros mit zwei Parametern (Argumente und Textkörper) definieren \XMLcenik
. \XMLnazev
Anschließend können Sie es mit TeX verarbeiten. Wenn diese Makros vorbereitet sind, können Sie die XML-Datei in einem TeX-Durchlauf verarbeiten:
\xmlprep {test.xml} {text.out}
\input test.out