joe 20 <" name="description" /> joe 20 <" />
78972

XSLT transformation to group similar tags

Question:

I have this XML with players and citizens sections. Each section has multiple person tags.

<?xml version="1.0" encoding="UTF-8"?> <test> <players> <person> <name>joe</name> <age>20</age> </person> <person> <name>sam</name> <age>23</age> </person> </players> <citizens> <person> <name>joe</name> <city>ny</city> </person> <person> <name>sam</name> <city>london</city> </person> </citizens> </test>

Now I want to transform this so that person tags of, players and citizens sections are merged together based on name tag.

This is the output I need.

<?xml version="1.0" encoding="UTF-8"?> <test> <players> <person> <name>joe</name> <age>20</age> <city>ny</city> </person> <person> <name>sam</name> <age>23</age> <city>london</city> </person> </players> </test>

I want to do an XSLT transformation for this. I tried lots of stuff without luck. Appreciate some help for this.

<strong>Update</strong>: I tried this.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:variable name="citizens" select="/test/citizens"/> <xsl:template match="/test/players"> <players> <xsl:apply-templates select="person"/> </players> </xsl:template> <xsl:template match="person"> <xsl:variable name="data1" select="."/> <xsl:variable name="data2" select="/test/citizens/person[name=current()/name]/."/> <person> <xsl:copy-of select="$data1/*"/> <xsl:for-each select="$data2/*"> <xsl:variable name="element2" select="name(.)"/> <xsl:if test="count($data1/*[name()=$element2])=0"> <xsl:copy-of select="."/> </xsl:if> </xsl:for-each> </person> </xsl:template> </xsl:stylesheet>

It's almost correct. I just want to get rid of last 2 person tags. Please guide me.

<players> <person> <name>joe</name> <age>20</age> <city>ny</city> </person> <person> <name>sam</name> <age>23</age> <city>london</city> </person> </players> <person> <name>joe</name> <city>ny</city> </person> <person> <name>sam</name> <city>london</city> </person>

Answer1:

Here's one way you could look at it:

<strong>XSLT 2.0</strong>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:key name="person-by-name" match="person" use="name" /> <!-- identity transform --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="/test"> <xsl:copy> <xsl:apply-templates select="players"/> </xsl:copy> </xsl:template> <xsl:template match="person"> <xsl:copy> <xsl:apply-templates/> <xsl:copy-of select="key('person-by-name', name, ../../citizens)/city "/> </xsl:copy> </xsl:template> </xsl:stylesheet> <hr />

Here's another:

<strong>XSLT 2.0</strong>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template match="/test"> <xsl:copy> <players> <xsl:for-each-group select="*/person" group-by="name"> <person> <xsl:copy-of select="name"/> <xsl:copy-of select="current-group()/*[not(self::name)]"/> </person> </xsl:for-each-group> </players> </xsl:copy> </xsl:template> </xsl:stylesheet>

Recommend

  • How to change a time zone in a data frame?
  • “non static method cannot be referenced from a static context” JPA Java
  • PHP - Setting inherited static property will also set it in other classes inheriting it
  • Put elements of a 1D vector into a 3D matrix using another matrix of positions
  • Pipe file contents in g++ to compile
  • Cursor with Stored Procedure Question
  • Error in dev.off() : cannot shut down device 1 (the null device)
  • Is there a way to return a sorted key list from a hash?
  • Filter Values of Current Week with XQuery
  • XPath expression with white space in node for defiant.js
  • Intellisense cannot infer type from extention method
  • Can I make `git merge` always conflict on file changes?
  • Meteor throws throwIfSelectorIsNotId exception
  • JPA - getting distinct value from one column
  • php regex remove digits
  • Add delivery info to query in SAP Crystal Reports
  • how to post with curl to REST/JSON service?
  • Max of several columns
  • Self join tutorial #10 on sqlzoo
  • Implicit property animations do not work with CAReplicatorLayer?
  • Change the width of the JQM panels
  • How to read data from a text file if the file location is not known in c#?
  • Update a record where _id = :id with Mongoose
  • View/Download Pdf Files in React - Router 4
  • What's a fast (non-loop) way to apply a dict to a ndarray (meaning use elements as keys and rep
  • android duplicate provider authority on apps that don't have provider
  • Merging rows to columns
  • Display images in Django
  • Word Open XML Mail Merge
  • Use of this Javascript
  • C++ Partial template specialization - design simplification
  • Get one-time binding to work for ng-if
  • Array.prototype.includes - not transformed with babel
  • Volley JsonObjectRequest send headers in GET Request
  • Importing jscolor library in angular 2
  • How to get next/previous record number?
  • SVN: Merging two branches together
  • Python: how to group similar lists together in a list of lists?
  • Easiest way to encapsulate a HTML5 webpage into an android app?
  • Recursive/Hierarchical Query Using Postgres