This is Interesting: Free Magazines for Graphics designers and webmasters  


Home > Archive > Microsoft XML > August 2004 > Difficulty Merging Two XML Documents with Namespaces





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Difficulty Merging Two XML Documents with Namespaces
John Sextro

2004-08-26, 7:17 pm

A call to all XML Gurus:

I am a relative newbie and have, what I consider a daunting task. I
need to merge two XML documents together. The only rules for the
merge are that doc2's values always win and the nodes are matched
using the Name attribute in the WebPart element. To complicate
matters each element has a namespace specified.

I imagine that the solution might involve striping off the namespaces
or something more elegant, like just handling the namespaces.
However, I have topped out on my skills and am in over my head. I've
included one set of matching nodes from the documents. Your help is
greatly appreciated.

Doc1:
<?xml version="1.0" encoding="utf-8" ?>
<Dashboard>
<WebPart Name="ACTeamSpace.HTM">
<contentclass xmlns="DAV:">urn:schemas-microsoft-com:webpart</contentclass>
<Title xmlns="urn:schemas-microsoft-com:webpart:">Admin Central
Bulletin Board</Title>
<Description xmlns="urn:schemas-microsoft-com:webpart:"/>
<ContentLink xmlns="urn:schemas-microsoft-com:webpart:">http://w3d.monsanto.com/asp/TSGetCookie.asp</ContentLink>
<XSL xmlns="urn:schemas-microsoft-com:webpart:"/>
<XSLLink xmlns="urn:schemas-microsoft-com:webpart:"/>
<MasterPartLink xmlns="urn:schemas-microsoft-com:webpart:"/>
<RequiresIsolation xmlns="urn:schemas-microsoft-com:webpart:">1</RequiresIsolation>
<ContentType xmlns="urn:schemas-microsoft-com:webpart:">0</ContentType>
<IsIncluded xmlns="urn:schemas-microsoft-com:webpart:">1</IsIncluded>
<AllowRemove xmlns="urn:schemas-microsoft-com:webpart:">1</AllowRemove>
<IsVisible xmlns="urn:schemas-microsoft-com:webpart:">1</IsVisible>
<FrameState xmlns="urn:schemas-microsoft-com:webpart:">0</FrameState>
<AllowMinimize xmlns="urn:schemas-microsoft-com:webpart:">1</AllowMinimize>
<HasFrame xmlns="urn:schemas-microsoft-com:webpart:">1</HasFrame>
<Zone xmlns="urn:schemas-microsoft-com:webpart:">2</Zone>
<PartOrder xmlns="urn:schemas-microsoft-com:webpart:">0</PartOrder>
<PartImageSmall xmlns="urn:schemas-microsoft-com:webpart:"/>
<CustomizationLink xmlns="urn:schemas-microsoft-com:webpart:"/>
<PartStorage xmlns="urn:schemas-microsoft-com:webpart:"/>
<Namespace xmlns="urn:schemas-microsoft-com:webpart:"/>
<DetailLink xmlns="urn:schemas-microsoft-com:webpart:"/>
<ParentID xmlns="urn:schemas-microsoft-com:dashboardfactory:">http://w3dd/DAVCatalog/Dashboards/Admin%20Central/</ParentID>
<Height xmlns="urn:schemas-microsoft-com:webpart:">400px</Height>
<PartImageLarge xmlns="urn:schemas-microsoft-com:webpart:"/>
<Width xmlns="urn:schemas-microsoft-com:webpart:"/>
<HelpLink xmlns="urn:schemas-microsoft-com:webpart:"/>
<CacheBehavior xmlns="urn:schemas-microsoft-com:webpart:">0</CacheBehavior>
<CacheTimeout xmlns="urn:schemas-microsoft-com:webpart:">0</CacheTimeout>
</WebPart>
</Dashboard>

Doc2:
<?xml version="1.0" encoding="utf-8" ?>
<Dashboard>
<WebPart Name="ACTeamSpace.HTM">
<Zone xmlns="urn:schemas-m_crosoft-com:webpart:">3</Zone>
<PartOrder xmlns="urn:schemas-m_crosoft-com:webpart:">1</PartOrder>
</WebPart>
</Dashboard>
Marrow

2004-08-26, 7:17 pm

Hi John,

You might find an XSLT solution useful? Something like...

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="doc2"
select="document('Doc2.xml',/)/Dashboard/WebPart"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>

<xsl:template match="WebPart">
<xsl:variable name="doc2parts" select="$doc2[@Name = current()/@Name]/*"/>
<xsl:copy>
<!-- process parts in doc1 and override with doc2 where necessary -->
<xsl:apply-templates select="@* | node()" mode="webparts">
<xsl:with-param name="doc2parts" select="$doc2parts"/>
</xsl:apply-templates>
<!-- process parts in doc2 - as they may be new -->
<xsl:apply-templates select="$doc2parts" mode="webparts2">
<xsl:with-param name="doc1parts" select="*"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>

<xsl:template match="*" mode="webparts">
<xsl:param name="doc2parts"/>
<xsl:variable name="doc2part" select="$doc2parts[local-name() =
local-name(current())]"/>
<xsl:apply-templates select="(.)[not($doc2part)] | $doc2part"/>
</xsl:template>

<xsl:template match="*" mode="webparts2">
<xsl:param name="doc1parts"/>
<xsl:if test="not($doc1parts[local-name() = local-name(current())])">
<xsl:apply-templates select="."/>
</xsl:if>
</xsl:template>

<xsl:template match="@* | text() | comment() | processing-instruction()"
mode="webparts">
<xsl:copy/>
</xsl:template>

<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="@* | text() | comment() | processing-instruction()">
<xsl:copy/>
</xsl:template>

</xsl:stylesheet>


HTH
Marrow
http://www.marrowsoft.com - home of Xselerator (XSLT IDE and debugger)
http://www.topxml.com/Xselerator


"John Sextro" <jcsext@monsanto.com> wrote in message
news:cb6a97fb.0408261057.6292251c@posting.google.com...
> A call to all XML Gurus:
>
> I am a relative newbie and have, what I consider a daunting task. I
> need to merge two XML documents together. The only rules for the
> merge are that doc2's values always win and the nodes are matched
> using the Name attribute in the WebPart element. To complicate
> matters each element has a namespace specified.
>
> I imagine that the solution might involve striping off the namespaces
> or something more elegant, like just handling the namespaces.
> However, I have topped out on my skills and am in over my head. I've
> included one set of matching nodes from the documents. Your help is
> greatly appreciated.
>
> Doc1:
> <?xml version="1.0" encoding="utf-8" ?>
> <Dashboard>
> <WebPart Name="ACTeamSpace.HTM">
> <contentclass

xmlns="DAV:">urn:schemas-microsoft-com:webpart</contentclass>
> <Title xmlns="urn:schemas-microsoft-com:webpart:">Admin Central
> Bulletin Board</Title>
> <Description xmlns="urn:schemas-microsoft-com:webpart:"/>
> <ContentLink

xmlns="urn:schemas-microsoft-com:webpart:">http://w3d.monsanto.com/asp/TSGet
Cookie.asp</ContentLink>
> <XSL xmlns="urn:schemas-microsoft-com:webpart:"/>
> <XSLLink xmlns="urn:schemas-microsoft-com:webpart:"/>
> <MasterPartLink xmlns="urn:schemas-microsoft-com:webpart:"/>
> <RequiresIsolation

xmlns="urn:schemas-microsoft-com:webpart:">1</RequiresIsolation>
> <ContentType xmlns="urn:schemas-microsoft-com:webpart:">0</ContentType>
> <IsIncluded xmlns="urn:schemas-microsoft-com:webpart:">1</IsIncluded>
> <AllowRemove xmlns="urn:schemas-microsoft-com:webpart:">1</AllowRemove>
> <IsVisible xmlns="urn:schemas-microsoft-com:webpart:">1</IsVisible>
> <FrameState xmlns="urn:schemas-microsoft-com:webpart:">0</FrameState>
> <AllowMinimize

xmlns="urn:schemas-microsoft-com:webpart:">1</AllowMinimize>
> <HasFrame xmlns="urn:schemas-microsoft-com:webpart:">1</HasFrame>
> <Zone xmlns="urn:schemas-microsoft-com:webpart:">2</Zone>
> <PartOrder xmlns="urn:schemas-microsoft-com:webpart:">0</PartOrder>
> <PartImageSmall xmlns="urn:schemas-microsoft-com:webpart:"/>
> <CustomizationLink xmlns="urn:schemas-microsoft-com:webpart:"/>
> <PartStorage xmlns="urn:schemas-microsoft-com:webpart:"/>
> <Namespace xmlns="urn:schemas-microsoft-com:webpart:"/>
> <DetailLink xmlns="urn:schemas-microsoft-com:webpart:"/>
> <ParentID

xmlns="urn:schemas-microsoft-com:dashboardfactory:">http://w3dd/DAVCatalog/D
ashboards/Admin%20Central/</ParentID>
> <Height xmlns="urn:schemas-microsoft-com:webpart:">400px</Height>
> <PartImageLarge xmlns="urn:schemas-microsoft-com:webpart:"/>
> <Width xmlns="urn:schemas-microsoft-com:webpart:"/>
> <HelpLink xmlns="urn:schemas-microsoft-com:webpart:"/>
> <CacheBehavior

xmlns="urn:schemas-microsoft-com:webpart:">0</CacheBehavior>
> <CacheTimeout xmlns="urn:schemas-microsoft-com:webpart:">0</CacheTimeout>
> </WebPart>
> </Dashboard>
>
> Doc2:
> <?xml version="1.0" encoding="utf-8" ?>
> <Dashboard>
> <WebPart Name="ACTeamSpace.HTM">
> <Zone xmlns="urn:schemas-m_crosoft-com:webpart:">3</Zone>
> <PartOrder xmlns="urn:schemas-m_crosoft-com:webpart:">1</PartOrder>
> </WebPart>
> </Dashboard>



John Sextro

2004-08-27, 12:16 pm

Marrow,

This is exactly the kind of solution I was looking for. I've
implemented the transformation using C#. It does generate the xml
document, however, it appears that the values from doc2 are not
overriding the values from doc1. What have I done wrong? I haven't
changed the xslt that you provided except to change the name of the
name of the document specified in the select attribute to the real
document name. Unfortunately, your xsl skills are far better than
mine and I have not had much luck deciphering this complex
transformation. If you have any ideas please let me know. Your help
is deeply appreciated and I thank you!

Regards,
John
Marrow

2004-08-27, 7:17 pm

Hi John,

In the .Net platform if the document() function fails to find the specified
document no exception/error is raised.

Put this template into that original stylesheet and see what the output
is...

<xsl:template match="Dashboard">
<xsl:choose>
<xsl:when test="not($doc2)">
<error>
<xsl:text>Either your other second XML document was not found or
does not contain the elements we're looking for</xsl:text>
</error>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

If you get an output XML with <error> in it - that means, well, what the
error says. In which case... check the name and path of the doc2. Also, if
doc2 is in a different path from doc1 (and you are specifying the full
path) - then change...
<xsl:variable name="doc2"
select="document('Doc2.xml',/)/Dashboard/WebPart"/>
to...
<xsl:variable name="doc2"
select="document('Doc2.xml')/Dashboard/WebPart"/>
(i.e. remove the second parameter of the document() function).

If you are still have probs - show the XML documents (aswell as their
filenames and paths) plus your XSL.

Cheers
Marrow
http://www.marrowsoft.com - home of Xselerator (XSLT IDE and debugger)
http://www.topxml.com/Xselerator


"John Sextro" <jcsext@monsanto.com> wrote in message
news:cb6a97fb.0408270556.4b1a141@posting.google.com...
> Marrow,
>
> This is exactly the kind of solution I was looking for. I've
> implemented the transformation using C#. It does generate the xml
> document, however, it appears that the values from doc2 are not
> overriding the values from doc1. What have I done wrong? I haven't
> changed the xslt that you provided except to change the name of the
> name of the document specified in the select attribute to the real
> document name. Unfortunately, your xsl skills are far better than
> mine and I have not had much luck deciphering this complex
> transformation. If you have any ideas please let me know. Your help
> is deeply appreciated and I thank you!
>
> Regards,
> John



Sponsored Links


Copyright 2003 - 2008 forum4designers.com  Software forum  Computer Hardware reviews