jbrehr
jbrehr

Reputation: 815

XSL: combining the results of two XML files

I am using XSL 3.0 to create a single XML file which combines two source XML files (XSL and both XML files in same directory). The sources are called people.xml and depositions.xml.

The people.xml file is a list of people, and it looks like this:

<personlist>
 <person id="foo_andrew">
  <lastname>Foo</lastname>
  <firstname>Andrew</firstname>
 </person>
 <person id="foo_barbara">
  <lastname>Foo</lastname>
  <firstname>Barbara</firstname>
 </person>
 <person id="foo_chris">
  <lastname>Foo</lastname>
  <firstname>Chris</firstname>
 </person>
 ...
</personlist>

These people from this file appear in the deposition file using the @id:

<corpus>
  <deposition id="1">
   <p n="1">Suspendisse eu nunc <person id="foo_andrew"/>tristique ex aliquam imperdiet. Quisque volutpat est sed <person id="foo_barbara"/>ullamcorper ultricies. Proin vel nunc in arcu tristique finibus.</p>
   <p n="2">Cras a dolor consequat,  <person id="foo_chris"/>congue leo et, porttitor mi. Integer pretium tellus id lobortis faucibus.</p>
   <p n="3">Quisque facilisis dui tincidunt <person id="foo_andrew"/>semper blandit. Aenean auctor sem augue, sit amet malesuada neque mattis id.</p>
  </deposition>
  <deposition id="2">
   <p n="1">Suspendisse eu nunc tristique ex aliquam imperdiet. Quisque volutpat est sed ullamcorper ultricies. Proin vel nunc in arcu tristique finibus.</p>
   <p n="2">Cras a dolor consequat, congue leo et, <person id="foo_barbara"/>porttitor mi. Integer pretium tellus id lobortis faucibus.</p>
   <p n="3">Quisque facilisis dui <person id="foo_chris"/>tincidunt semper blandit. Aenean auctor sem augue, sit amet malesuada neque mattis id.</p>
  </deposition>
  <deposition id="3">
   <p n="1">Suspendisse eu nunc tristique <person id="foo_chris"/>ex aliquam imperdiet. Quisque volutpat est sed ullamcorper ultricies. Proin vel nunc in arcu tristique finibus.</p>
   <p n="2">Cras a <person id="foo_andrew"/>dolor consequat, congue leo et, porttitor mi. Integer pretium tellus id lobortis faucibus.</p>
   <p n="3">Quisque <person id="foo_barbara"/>facilisis dui tincidunt semper blandit. Aenean auctor sem augue, sit amet malesuada neque mattis id.</p>
  </deposition>
</corpus>

I would like to output an XML file that takes combines every appearance of the person into one file. It would look something like the following, where - a <deposition> is created for each time the person appears in a deposition - but only one <deposition> is created, even if they appear multiple times

<personappear>
 <person id="foo_andrew">
  <lastname>Foo</lastname>
  <firstname>Andrew</firstname>
  <listappear>
   <deposition>1</deposition>
   <deposition>3</deposition>
  </listappear>
 </person>
 <person id="foo_barbara">
  <lastname>Foo</lastname>
  <firstname>Barbara</firstname>
  <listappear>
   <deposition>1</deposition>
   <deposition>2</deposition>
   <deposition>3</deposition>
  </listappear>
 </person>
 <person id="foo_chris">
  <lastname>Foo</lastname>
  <firstname>Chris</firstname>
  <listappear>
   <deposition>1</deposition>
   <deposition>2</deposition>
   <deposition>3</deposition>
  </listappear>
 </person>
 ...
</personlist>

I can't figure even figure out the basics of how to access two separate XML files in one XSL! This is blocking me from deploying keys, etc to combine the records.

Thanks very much in advance.

Upvotes: 0

Views: 49

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167716

As for loading a secondary document, use doc('depositions.xml') or document('depositions.xml'). For the reference you are right that a key helps:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    expand-text="yes"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output indent="yes"/>

  <!-- make <xsl:param name="deposition-doc" select="doc('depositions.xml')"/> -->
  <xsl:param name="deposition-doc">
    <corpus>
      <deposition id="1">
       <p n="1">Suspendisse eu nunc <person id="foo_andrew"/>tristique ex aliquam imperdiet. Quisque volutpat est sed <person id="foo_barbara"/>ullamcorper ultricies. Proin vel nunc in arcu tristique finibus.</p>
       <p n="2">Cras a dolor consequat,  <person id="foo_chris"/>congue leo et, porttitor mi. Integer pretium tellus id lobortis faucibus.</p>
       <p n="3">Quisque facilisis dui tincidunt <person id="foo_andrew"/>semper blandit. Aenean auctor sem augue, sit amet malesuada neque mattis id.</p>
      </deposition>
      <deposition id="2">
       <p n="1">Suspendisse eu nunc tristique ex aliquam imperdiet. Quisque volutpat est sed ullamcorper ultricies. Proin vel nunc in arcu tristique finibus.</p>
       <p n="2">Cras a dolor consequat, congue leo et, <person id="foo_barbara"/>porttitor mi. Integer pretium tellus id lobortis faucibus.</p>
       <p n="3">Quisque facilisis dui <person id="foo_chris"/>tincidunt semper blandit. Aenean auctor sem augue, sit amet malesuada neque mattis id.</p>
      </deposition>
      <deposition id="3">
       <p n="1">Suspendisse eu nunc tristique <person id="foo_chris"/>ex aliquam imperdiet. Quisque volutpat est sed ullamcorper ultricies. Proin vel nunc in arcu tristique finibus.</p>
       <p n="2">Cras a <person id="foo_andrew"/>dolor consequat, congue leo et, porttitor mi. Integer pretium tellus id lobortis faucibus.</p>
       <p n="3">Quisque <person id="foo_barbara"/>facilisis dui tincidunt semper blandit. Aenean auctor sem augue, sit amet malesuada neque mattis id.</p>
      </deposition>
    </corpus>      
  </xsl:param>

  <xsl:key name="ref" match="deposition" use=".//person/@id"/>

  <xsl:template match="person">
      <xsl:copy>
          <xsl:copy-of select="@*, node()"/>
          <listappear>
              <xsl:for-each select="key('ref', @id, $deposition-doc)">
                  <deposition>{@id}</deposition>
              </xsl:for-each>
          </listappear>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/jyH9rMf

Upvotes: 1

Related Questions