0

I want to merge text that is split between corresponding attributes within a huge xml document. I thought I could do this using regular expressions (move a string between to strings at the end of another string) but as was pointed out to me that would be a poor choice of weapons and XSLT was recommended instead. Now I know nothing about xslt and parsing but I am getting started with python and I think that this should be possible using python. Here is what my input looks like:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="footnotes.xsl"?>
<start>
<p>
vielen Delicten mit großer Conſequenz durchgeführt
<note place="foot" n="(h)" xml:id="seg2pn_2_1" next="#seg2pn_2_2">aaa <hi rendition="#aq">some text</hi> <hi rendition="#g">aaa</hi></note>
. —
<lb/>
Ganz dieſelben Grundſätze aber gelten auch bey ſolchen
<lb/>
Obligationen, deren erſte Entſtehung nicht in einem De-
<lb/>
lict, ſondern in einem Vertrag u. ſ. w., enthalten iſt, wo-
<lb/>
bey aber die einzelne Anwendung der Klage auf einen
<lb/>
<lb/>
Dolus ſich gründet
. — Und eben ſo werden dieſe Grund-
<lb/>
ſätze auch auf die Beſtrafung öffentlicher Verbrechen an-
<lb/>
gewendet, bey welchen ganz beſonders hervorgehoben wird,
<lb/>
daß die Zurechnung von der mehr oder weniger einfachen
<lb/>
und leicht einzuſehenden Natur des Verbrechens abhängig
<lb/>
ſeyn ſoll

</p>
<lb/>
<p>
<hi rendition="#aq">III.</hi>
Bey der
<hi rendition="#g">Auflöſung der Obligationen</hi>
iſt
<lb/>
die Anwendung des Grundſatzes einfach und unbedenklich.
<lb/>
Der Unmündige kann einen Erlaßvertrag ſchließen: wenn
<lb/>
er Schuldner iſt für ſich allein, als Glaubiger aber nur
<lb/>
mit dem Tutor
<note place="foot" n="(l)">
<hi rendition="#aq">
<hi rendition="#i">L.</hi>
28
<hi rendition="#i">pr. de pactis</hi>
</hi>
(2. 14.).
</note>
. — Zahlung leiſten würde er können,
<lb/>
weil er dadurch Befreyung erwirbt: dennoch kann er es
<lb/>
nicht ohne Tutor, weil es nicht geſchehen kann ohne Ver-
<lb/>
äußerung des Geldes. Ganz eben ſo verhält es ſich mit
<lb/>
dem Empfang einer Zahlung, wodurch er zwar Geld er-
<lb/>
wirbt, auf der andern Seite aber auch eine Forderung
<lb/>
verliert
<note place="foot" n="(m)" xml:id="seg2pn_3_1" next="#seg2pn_3_2">some text CCC some text</note>
.
</p>
<lb/>
<p>
<note place="foot" n="(h)" xml:id="seg2pn_2_2" prev="#seg2pn_2_1"><hi rendition="#aq">bbb</hi> <hi rendition="#g">some text bbb</hi></note>
</p>
<lb/>

<lb/>
<p>
<hi rendition="#aq">IV.</hi>
Die
<hi rendition="#g">Prozeßführung</hi>
, der Unmündige mag nun
<lb/>
Kläger oder Beklagter ſeyn, iſt wegen des ungewiſſen
<lb/>
Ausgangs ſtets ein gefährliches Geſchäft; daher iſt dazu
<lb/>
der Unmündige fähig nur mit Genehmigung des Tutors

</p>
<lb/>
<lb/>
<p>
<hi rendition="#aq">VI.</hi>
<hi rendition="#g">Sponſalien</hi>
ſchließen kann der Unmündige für
<lb/>
ſich allein

, welches ſo zu erklären iſt. Steht er in
<lb/>
väterlicher Gewalt, ſo iſt er ohnehin, auch unabhängig
<lb/>
von dem unreifen Alter, an des Vaters Einwilligung ſtreng
<lb/>
gebunden. Iſt er unabhängig, ſo konnte freylich die Ge-
<lb/>
nehmigung des Tutors nicht aushelfen, da dieſe ſich nur
<lb/>
auf das Vermögen bezieht, womit die Sponſalien nicht in
<lb/>
Verbindung ſtehen. Man möchte alſo, nach der Analogie
<lb/>
<note place="foot" n="(m)" xml:id="seg2pn_3_2" prev="#seg2pn_3_1">DDD <hi rendition="#aq">some Text</hi> <hi rendition="#g">DDD</hi> </note>
<lb/>
<pb n="46" facs="#f0058"/>
Buch
<hi rendition="#aq">II.</hi>
Rechtsverhältniſſe. Kap.
<hi rendition="#aq">III.</hi>

</p>
</start>

desired output: The before seperated footnotes should be merged + there position of the merge should be marked. Like this:

<note place="foot" n="(h)" xml:id="seg2pn_2_1" next="#seg2pn_2_2">aaa <hi rendition="#aq">some text</hi> <hi rendition="#g">aaa</hi>∀<hi rendition="#aq">bbb</hi> <hi rendition="#g">some text bbb</hi></note>

Note that the footnote text can be formatted in various ways – the attributes <hi rendition="#aq" and <hi rendition="#g" are only two examples that may appear. The identity transform according to this advice should look like this as I removed all the namespaces:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="note[@place='foot'][@next]">
  <xsl:copy>
    <xsl:value-of select="."/>
    <xsl:value-of select="id(substring(@next, 2))"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="note[@place='foot'][@prev]"/>
</xsl:stylesheet>

So my question is: how would a python script look like to write the desired output to a new xml file?

3
  • Start with the documentation lxml.de/xpathxslt.html#xslt and tell us where/how you fail if you don't get it to work. Commented Jan 26, 2022 at 20:41
  • 1
    Also note that your stylesheet doesn't have the identity transformation templates, you just have the rules you were told to add. Commented Jan 26, 2022 at 20:53
  • Not sure what exactly your difficulty is. The contents of both the XML and the XSLT files is irrelevant to the question of how to initialize the transformation using Python (or any other tool). Commented Jan 26, 2022 at 21:10

1 Answer 1

1

Does this generate the output you expect?

import lxml.etree

xml_in  = 'footnotes.xml'
xml_out = 'result.xml'

xslt = lxml.etree.fromstring('''
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

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

    <!--do nothing for <note prev=""> tags-->
    <xsl:template match="note[@place='foot'][@prev]"/>

    <xsl:template match="note[@place='foot'][@next]">
      <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
        <xsl:text>∀</xsl:text>
        <xsl:copy-of select="id(substring(@next, 2))/node()"/>
      </xsl:copy>
    </xsl:template>
  </xsl:stylesheet>'''
)


doc = lxml.etree.parse(xml_in)

with open(xml_out, 'w') as f:
    print(str(doc.xslt(xslt)), file=f)

Before:

<note place="foot" n="(h)" xml:id="seg2pn_2_1" next="#seg2pn_2_2">
  aaa1 <hi rendition="#aq">some text</hi> <hi rendition="#g">aaa2</hi>
</note>
<note place="foot" n="(m)" xml:id="seg2pn_3_1" next="#seg2pn_3_2">
  some text CCC some text
</note>
<note place="foot" n="(h)" xml:id="seg2pn_2_2" prev="#seg2pn_2_1">
  <hi rendition="#aq">bbb1</hi> <hi rendition="#g">some text bbb2</hi>
</note>
<note place="foot" n="(m)" xml:id="seg2pn_3_2" prev="#seg2pn_3_1">
  DDD1 <hi rendition="#aq">some Text</hi> <hi rendition="#g">DDD2</hi>
</note>
<note place="foot" n="(ii)" xml:id="seg2pn_10_10" next="#seg2pn_10_11">
  one one one
</note>
<note place="foot" n="(ii)" xml:id="seg2pn_10_11" prev="#seg2pn_10_10">
  two two two
</note>

After:

<note place="foot" n="(h)" xml:id="seg2pn_2_1" next="#seg2pn_2_2">
  aaa1 <hi rendition="#aq">some text</hi> <hi rendition="#g">aaa2</hi>
  ∀
  <hi rendition="#aq">bbb1</hi> <hi rendition="#g">some text bbb2</hi>
</note>

<note place="foot" n="(m)" xml:id="seg2pn_3_1" next="#seg2pn_3_2">
  some text CCC some text
  ∀
  DDD1 <hi rendition="#aq">some Text</hi> <hi rendition="#g">DDD2</hi>
</note>

<note place="foot" n="(ii)" xml:id="seg2pn_10_10" next="#seg2pn_10_11">
  one one one
  ∀
  two two two
</note>
Sign up to request clarification or add additional context in comments.

14 Comments

That works perfect! One thing: is it possible to mark the position of the merge with a special sign like an ∀ or a £?. Sometimes I need to add a space and sometimes I need to delete a "-" . So I need a marker for this position.
So that's what that character was. Yes, it is. One way is to concat() the strings - I've edited the code.
This is it! I don’t know what to say. Thanks a lot!
Hm, ok. If you can add an example of it I can take another look.
Thanks - that helped. Code updated.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.