• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 57
  • Last Modified:

Remove repeated nodes from XML

I am having trouble filtering some XML.  I think I need to use Xquery, but apart from dabbling with them as text files, I am quite new to XML.  

I have the following XML (below) that I need to exclude some nodes from.  

In short, the XML contains <Entries> with a LOT of <Entry> nodes.
Each <Entry> contains <Contacts> with a lot of <Contact> nodes.  

I basically need to remove most of the <contact> nodes, leaving just the first one in each <contacts> node.  

I  want just the first <contact> node to persist along with all of the other data in an <entry>

The title of this question may lead you to think that the extra <contact> nodes are duplicates.  they are not.  They may contain different data, but I just want the first <contact> for each <Entry>

I have seen queries to return the first node where there are siblings with the same name, which would possibly form part of the solution, but I don't know how to wrap it all up so I get all of the XML EXCEPT the extra <Contact> nodes.  

Any help here would be greatly appreciated.  And an Xquery that does it for me would be perfect.  

Thankyou in advance.  

XML below:


<Entries>
<Entry Id="2">
<ChangeCountry>Australia</ChangeCountry>
<DialCode>61</DialCode>
<Organisation>
  <Name><![CDATA[Organisation 1]]></Name>
  <TelephoneNumber><![CDATA[11 111 111]]></TelephoneNumber>
  <FaxNumber><![CDATA[22 222 222]]></FaxNumber>
  <EmailAddress><![CDATA[john@john.com]]></EmailAddress>
  <WebsiteUrl><![CDATA[www.john.com]]></WebsiteUrl>
</Organisation>
<Contacts>
<Contact>
<JobTitle><![CDATA[director]]></JobTitle>
<Title><![CDATA[Mr]]></Title>
<FirstName><![CDATA[Johnny]]></FirstName>
<LastName><![CDATA[Boy]]></LastName>
<TelephoneNumber><![CDATA[111222333]]></TelephoneNumber>
<FaxNumber><![CDATA[]]></FaxNumber>
<EmailAddress><![CDATA[john2@john.com]]></EmailAddress>
<WebsiteUrl><![CDATA[www2.john.com]]></WebsiteUrl>
<TwitterName><![CDATA[]]></TwitterName>
<FacebookUrl><![CDATA[]]></FacebookUrl>
<Address>
<Line1><![CDATA[]]></Line1>
<Line2><![CDATA[]]></Line2>
<Line3><![CDATA[]]></Line3>
<State><![CDATA[]]></State>
<City><![CDATA[]]></City>
<ZipCode><![CDATA[]]></ZipCode>
<Country><![CDATA[]]></Country>
</Address>
</Contact>

<Contact>
<JobTitle><![CDATA[director]]></JobTitle>
<Title><![CDATA[Mr]]></Title>
<FirstName><![CDATA[Jimmy]]></FirstName>
<LastName><![CDATA[Bob]]></LastName>
<TelephoneNumber><![CDATA[111222334]]></TelephoneNumber>
<FaxNumber><![CDATA[]]></FaxNumber>
<EmailAddress><![CDATA[jim@bob.com]]></EmailAddress>
<WebsiteUrl><![CDATA[www.bob.com]]></WebsiteUrl>
<TwitterName><![CDATA[]]></TwitterName>
<FacebookUrl><![CDATA[]]></FacebookUrl>
<Address>
<Line1><![CDATA[]]></Line1>
<Line2><![CDATA[]]></Line2>
<Line3><![CDATA[]]></Line3>
<State><![CDATA[]]></State>
<City><![CDATA[]]></City>
<ZipCode><![CDATA[]]></ZipCode>
<Country><![CDATA[]]></Country>
</Address>
</Contact>

</Contacts>
</Entry>
<... Many more entries... >
</Entries>

Open in new window

0
John
Asked:
John
  • 3
  • 3
  • 2
  • +1
2 Solutions
 
ste5anSenior DeveloperCommented:
It is essentials for XML related questions that you post valid (well formed) XML.
0
 
JohnAuthor Commented:
Just remove the <... Many more entries... > line and it should be OK
0
 
MurpheyApplication ConsultantCommented:
Hello John,

Not realy a tool, but 2 steps:

1. Copy past the XML to the inbox from xht XSD generator https://www.freeformatter.com/xsd-generator.html
(Select Generate in new window)

2. Copy the generated result into the inbox of http://xsd2xml.com/
  The result will show the undoubled XML.

If you like to have it for documentation, past the XSD output to  http://visualxsd.com/
Click "Generate XSD structure"
Click "+Expand All"

Nice :-)
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
Geert BormansInformation ArchitectCommented:
Please don't go hacking with copy paste in online services....

This can be done using XQuery, but you would be reconstructing the tree with some hardcode instructions

For this kind of transformations, I would recommend XSLT over XQuery, mainly because XSLT does reconstruction fairly straightforward
I take the liberty of suggesting XSLT because of this
I think I need to use Xquery,

Here is all the XSLT you need

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="1.0">
    
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>
    
    <xsl:template match="node()">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Contacts/Contact[preceding-sibling::Contact]"/>
    
</xsl:stylesheet>

Open in new window


Think about it, if you really need an XQuery (which will be a lot more complex) I will do one
0
 
Geert BormansInformation ArchitectCommented:
The first template does a nested deep copy it get triggered for most of the nodes
The second template only gets triggered when a Contact inside Contacts has a preceding sibling Contact (meaning it is not the first contact)
Since that one is empty, it means nothing gets copied to the output tree at that level.... so, it blanks the entire subtree... what you want
0
 
JohnAuthor Commented:
This looks really good thanks.  We are just testing it.
0
 
MurpheyApplication ConsultantCommented:
Geert Bormans is probably right about online activities, but anyway,
If you like to have it for documentation or like a graphical presentation, paste the XSD output to  http://visualxsd.com/

This is really cool!
0
 
Geert BormansInformation ArchitectCommented:
The proposed solution is complete, is tested and relevant as per the original question.  Just a pitty we never got feedback on the testing
0
 
JohnAuthor Commented:
This was passed on and works great thankyou
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

  • 3
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now