У меня есть следующее XML
содержимое файла, которое я преобразую, используя lxml и XSLT.
contents.xml
<division id="ch.3-pt.1-div.4" guid="_172f071b-3e58-4780-9764-486f8ef6105c" affected.by.uncommenced="0" numbering.style="manual">
<no>Division 4</no>
<heading id="ch.3-pt.1-div.4-he" guid="_7674f8f8-89f8-4947-8457-36064bf4d157">Clinical waste disposal</heading>
<clause id="sec.20" guid="_3b10e1a6-5526-4655-85f6-90dee5425aee" affected.by.uncommenced="0" spent.amends="0" provision.type="other">
<no>20</no>
<heading id="sec.20-he" guid="_5ab98572-56f2-4c22-8c1c-b1274f9cd6a2">Untreated clinical waste disposal</heading>
<subclause id="sec.20-ssec.1" guid="_c3831668-e2f1-4ba2-95bd-a41d0b6e7973" affected.by.uncommenced="0" provision.type="other">
<no>(1)</no>
<block>
<txt break.before="0">A person must not deliver untreated clinical waste to a facility for disposal under <intref refid="sch.2" target.guid="_d1f92e33-15ef-42ef-ae13-4f6d916109e0" check="valid">schedule 2</intref>, <intref refid="sch.2-sec.60" target.guid="_dab3fb38-8f7b-479c-99ee-caba191c3cf2" check="valid">section 60</intref><intref refid="sch.2-sec.60-ssec.1" target.guid="_b8b31412-9d9f-4fd4-82e4-74d6eb6b0d1b" check="valid">(1)</intref><intref refid="sch.2-sec.60-ssec.1-para1.b" target.guid="_a2af180c-2fe6-42c7-ae0e-299a693fd5ae" check="valid">(b)</intref> unless the waste was generated in a scheduled area.</txt>
</block>
<penalty id="sec.20-ssec.1-pen" guid="_0fb13eb2-cccb-4022-9abf-4309d0132ed5">
<block>
<txt break.before="1">Maximum penalty—20 penalty units.</txt>
</block>
</penalty>
</subclause>
</clause>
</division>
contents.xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://docs.oasis-open.org/legaldocml/ns/akn/3.0/WD17" xmlns:date="http://exslt.org/dates-and-times" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output method="xml" indent="yes" encoding="UTF-8" />
<xsl:template match="/">
<akomaNtoso xmlns="http://docs.oasis-open.org/legaldocml/ns/akn/3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://docs.oasis-open.org/legaldocml/ns/akn/3.0 http://docs.oasis-open.org/legaldocml/akn-core/v1.0/cos01/part2-specs/schemas/akomantoso30.xsd">
<xsl:apply-templates />
</akomaNtoso>
</xsl:template>
<!-- Copy all nodes but strip attributes (modified identity transform) -->
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="division/clause/block">
<xsl:choose>
<xsl:when test="definition">
<wrapUp>
<xsl:apply-templates select="definition" />
</wrapUp>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- THIS IS THE PART I EXPECT TO WORK FOR ME BUT IT DOES NOT -->
<!-- Match all penalty or blocks under subclause and put them in a content node -->
<xsl:template match="clause/subclause/*[name()='block' or name()='penalty']">
<xsl:choose>
<xsl:when test="table">
<wrapUp>
<xsl:apply-templates select="table" />
</wrapUp>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates /> <!-- THIS DOES NOT WORK -->
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Match all blocks after clause/[no,heading] but not blocks with lists as 2nd nodes -->
<xsl:template match="//clause[heading[1]]/block[name(*[2]) != 'list']">
<content>
<xsl:apply-templates />
</content>
</xsl:template>
<xsl:template match="subclause">
<subsection>
<xsl:attribute name="eId">
<xsl:value-of select="@id" />
</xsl:attribute>
<xsl:apply-templates />
</subsection>
</xsl:template>
<!-- Match all blocks with first element as txt and second element is not list -->
<xsl:template match="//subclause/block[txt[1] and name(*[2]) != 'list' and name(*[2]) != 'deflist']">
<content>
<xsl:apply-templates />
</content>
</xsl:template>
</xsl:stylesheet>
Моя проблема в том, что когда я запускаю следующее преобразование, он не добавляет узел penalty
внутри block
над ним.
То, что я получаю:
<?xml version="1.0" encoding="UTF-8"?>
<akomaNtoso xmlns="http://docs.oasis-open.org/legaldocml/ns/akn/3.0" xmlns:date="http://exslt.org/dates-and-times" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://docs.oasis-open.org/legaldocml/ns/akn/3.0 http://docs.oasis-open.org/legaldocml/akn-core/v1.0/cos01/part2-specs/schemas/akomantoso30.xsd">
<division xmlns="">
<no>Division 4</no>
<heading>Clinical waste disposal</heading>
<clause>
<no>20</no>
<heading>Untreated clinical waste disposal</heading>
<subsection xmlns="http://docs.oasis-open.org/legaldocml/ns/akn/3.0/WD17" eId="sec.20-ssec.1">
<no xmlns="">(1)</no>
<content>
<txt xmlns="">
A person must not deliver untreated clinical waste to a facility for disposal under
<intref>schedule 2</intref>
,
<intref>section 60</intref>
<intref>(1)</intref>
<intref>(b)</intref>
unless the waste was generated in a scheduled area.
</txt>
</content>
<!-- THIS IS WHERE MY PROBLEM IS, IT IS OUTSIDE content ABOVE -->
<block xmlns="">
<txt>Maximum penalty—20 penalty units.</txt>
</block>
</subsection>
</clause>
</division>
</akomaNtoso>
Что я ожидаю, так это:
<?xml version="1.0" encoding="UTF-8"?>
<akomaNtoso xmlns="http://docs.oasis-open.org/legaldocml/ns/akn/3.0" xmlns:date="http://exslt.org/dates-and-times" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://docs.oasis-open.org/legaldocml/ns/akn/3.0 http://docs.oasis-open.org/legaldocml/akn-core/v1.0/cos01/part2-specs/schemas/akomantoso30.xsd">
<division xmlns="">
<no>Division 4</no>
<heading>Clinical waste disposal</heading>
<clause>
<no>20</no>
<heading>Untreated clinical waste disposal</heading>
<subsection xmlns="http://docs.oasis-open.org/legaldocml/ns/akn/3.0/WD17" eId="sec.20-ssec.1">
<no xmlns="">(1)</no>
<content>
<txt xmlns="">
A person must not deliver untreated clinical waste to a facility for disposal under
<intref>schedule 2</intref>
,
<intref>section 60</intref>
<intref>(1)</intref>
<intref>(b)</intref>
unless the waste was generated in a scheduled area.
</txt>
<!-- THIS SHOULD BE INSIDE THE content BLOCK LIKE THIS AFTER TRANSFORMATION COS penalty IS TRANSFORMED TO content-->
<block xmlns="">
<txt>Maximum penalty—20 penalty units.</txt>
</block>
</content>
</subsection>
</clause>
</division>
</akomaNtoso>
Код, который я запускаю:
main.py
from lxml import etree
def transform_xml(tree, xslt_path):
"""Transforms an xml tree given an xslt."""
try:
transformer = etree.XSLT(etree.parse(xslt_path))
tree = transformer(tree)
return tree, None
except (etree.XSLTParseError, etree.XMLSyntaxError) as error:
return None, f"{error}"
if __name__ == "__main__":
tree = """
<division id="ch.3-pt.1-div.4" guid="_172f071b-3e58-4780-9764-486f8ef6105c" affected.by.uncommenced="0" numbering.style="manual">
<no>Division 4</no>
<heading id="ch.3-pt.1-div.4-he" guid="_7674f8f8-89f8-4947-8457-36064bf4d157">Clinical waste disposal</heading>
<clause id="sec.20" guid="_3b10e1a6-5526-4655-85f6-90dee5425aee" affected.by.uncommenced="0" spent.amends="0" provision.type="other">
<no>20</no>
<heading id="sec.20-he" guid="_5ab98572-56f2-4c22-8c1c-b1274f9cd6a2">Untreated clinical waste disposal</heading>
<subclause id="sec.20-ssec.1" guid="_c3831668-e2f1-4ba2-95bd-a41d0b6e7973" affected.by.uncommenced="0" provision.type="other">
<no>(1)</no>
<block>
<txt break.before="0">A person must not deliver untreated clinical waste to a facility for disposal under <intref refid="sch.2" target.guid="_d1f92e33-15ef-42ef-ae13-4f6d916109e0" check="valid">schedule 2</intref>, <intref refid="sch.2-sec.60" target.guid="_dab3fb38-8f7b-479c-99ee-caba191c3cf2" check="valid">section 60</intref><intref refid="sch.2-sec.60-ssec.1" target.guid="_b8b31412-9d9f-4fd4-82e4-74d6eb6b0d1b" check="valid">(1)</intref><intref refid="sch.2-sec.60-ssec.1-para1.b" target.guid="_a2af180c-2fe6-42c7-ae0e-299a693fd5ae" check="valid">(b)</intref> unless the waste was generated in a scheduled area.</txt>
</block>
<penalty id="sec.20-ssec.1-pen" guid="_0fb13eb2-cccb-4022-9abf-4309d0132ed5">
<block>
<txt break.before="1">Maximum penalty—20 penalty units.</txt>
</block>
</penalty>
</subclause>
</clause>
</division>
"""
tree = etree.XML(tree)
xslt_path = "xslt/convert.xslt"
tree, error = transform_xml(tree, xslt_path)
print(tree)
print(error)
Я довольноновичок в XSLT
, как мне этого добиться?