portfolio-performance / portfolio

Track and evaluate the performance of your investment portfolio across stocks, cryptocurrencies, and other assets.
http://www.portfolio-performance.info
Eclipse Public License 1.0
2.75k stars 577 forks source link

Support XML format using 'id' attributes to encode references (XStream.ID_REFERENCES) #4117

Open pfalcon opened 3 days ago

pfalcon commented 3 days ago

This patchset implements supports for XML serialization format using 'id' attributes to encode references, as discussed in https://github.com/portfolio-performance/portfolio/issues/3417 . To summarize discussion in that ticket, the main motivation for supporting this format is enabling easy interoperability with 3rd-party tools.

What this patch implements is:

  1. "Save as" -> "XML with id attributes" command in the "File" menu.
  2. Detection of XPath vs id format when opening plain XML files. XStream library itself doesn''t do such autodetection. The detection works only for plain XML files, not zipped, not encrypted. That should be a fair compromise, given the aim is interoperability with external tools.
  3. Format is preserved for saving. I.e., XML id files will be saved as such going forwards, while XPath file will be saved as such.
  4. There're tweaks to avoid putting id attributes on elements which aren't referenceable with existing PP data/object model. The absolute minimum which requires such treatment is <price> element. But again, I went as far as diffing original XPath XML vs id XML produced from it, to make sure that diff doesn't have spurious id's on elements which can't really be referenced. Perhaps the only exception is <watchlist>. These don't have uuid in PP model, effectively name is an ID, but for external tools, it's useful to have some formal ID for them, so XML id attr is produced.
pfalcon commented 3 days ago

Example of the XML diff, based on the included kommer example:

@@ -553,23 +553,23 @@
                   <updatedAt>2024-02-16T07:17:00.710324Z</updatedAt>
                   <type>BUY</type>
                 </portfolio-transaction>
-                <portfolio-transaction>
+                <portfolio-transaction id="26">
                   <uuid>68448a62-ab45-4233-abc3-cae984c05f6a</uuid>
                   <date>2019-01-07T00:00</date>
                   <currencyCode>EUR</currencyCode>
                   <amount>133025</amount>
-                  <security reference="../../../../../../../../../securities/security[5]"/>
-                  <crossEntry class="buysell">
-                    <portfolio reference="../../../.."/>
-                    <portfolioTransaction reference="../.."/>
-                    <account reference="../../../../../../../.."/>
-                    <accountTransaction>
+                  <security reference="6"/>
+                  <crossEntry class="buysell" id="27">
+                    <portfolio reference="24"/>
+                    <portfolioTransaction reference="26"/>
+                    <account reference="20"/>
+                    <accountTransaction id="28">
                       <uuid>ff6462ad-dd45-4bd6-a8c2-3806ab449ed4</uuid>
                       <date>2019-01-07T00:00</date>
                       <currencyCode>EUR</currencyCode>
                       <amount>133025</amount>