Skip to content

Instantly share code, notes, and snippets.

@martin-honnen
Created July 21, 2023 14:01
Show Gist options
  • Select an option

  • Save martin-honnen/93d9290969b70646e68a5d2097ab3cf5 to your computer and use it in GitHub Desktop.

Select an option

Save martin-honnen/93d9290969b70646e68a5d2097ab3cf5 to your computer and use it in GitHub Desktop.
Merge two XML documents with XSLT 3 and nested grouping
<?xml version="1.0" encoding="utf-8"?>
<permissions>
<privapp-permissions package="a">
<permission name="x"/>
<permission name="y"/>
</privapp-permissions>
</permissions>
<?xml version="1.0" encoding="utf-8"?>
<permissions>
<privapp-permissions package="a">
<permission name="x"/>
<permission name="z"/>
</privapp-permissions>
</permissions>
from saxonche import PySaxonProcessor
with PySaxonProcessor(license=False) as saxon:
xslt30_processor = saxon.new_xslt30_processor()
xslt30_processor.transform_to_file(source_file='a.xml', stylesheet_file='merge-with-grouping.xsl', output_file='merged-result.xml')
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all">
<xsl:template match="permissions">
<xsl:copy>
<xsl:for-each-group select="privapp-permissions, $doc2/permissions/privapp-permissions" group-by="@package">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:for-each-group select="current-group()/*" group-by="@name">
<xsl:copy-of select="."/>
</xsl:for-each-group>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:output method="xml" indent="yes"/>
<xsl:param name="doc2" as="document-node()" select="doc('b.xml')"/>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<permissions>
<privapp-permissions package="a">
<permission name="x"/>
<permission name="y"/>
<permission name="z"/>
</privapp-permissions>
</permissions>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment