Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

HELP Needed: How To Find circular dependencies in XML

Status
Not open for further replies.

DocDinDc

Technical User
Jan 14, 2010
1
US
Hello All,

I am a newbie to this forum and have confronted with the daunting task of finding circular/looped dependencies within an XML file.

The XML nodes and elements represent fields with options, whereas Field A has 3 options and Field A, Option 2 spawns Field B, and so on.

My goal is find any circular dependencies that exist within the fields (more than 100 with > 200 dependency relationships) and remove them. An example of this would be if Field B, option 2, spawns Field A.

Are there any tools out there to represent this in a graphical output or textually identify which nodes are circular?

Thanks in Advance!

-Doc
 
[0]>I am a newbie to this forum
That may play to your advantage. In some cases, I would give up helping for some veterans to the forum if I judge help would be vain and even counter-productive.

[1] With arsenal from within the boundary of xml technologies, it is possible to approach the problem of some affinity to traveler problem and/or paths and loops over a lattice etc. It is not apriori simple and the inherent complexity is recognized.

[2] Xsl basically kind of functional language should be adequate to tackle the problem. In a sense, it can be conceived as a kind of constraint on xml document through Schematron, outside of w3c schema language.

[3] I can show you an example of how this can be done through recursive template construction. Concrete use to your document is up to you to re-modeling the demo.

[4] Suppose the xml be this with general structure in a way realizing what you describe as the problem.
[tt]
<root>
<field name="a">
<option name="p" />
<option name="q" />
</field>
<field name="b">
<option name="r" />
<option name="s" />
<option name="t" />
</field>
<field name="p">
<option name="w" />
<option name="b" />
<option name="p" />
<option name="a" />
</field>
<field name="s">
<option name="x" />
<option name="y" />
</field>
</root>
[/tt]
[5] This is a way to get all the path with the characteristic suggestive to dependency.
[tt]
<xsl:stylesheet version="1.0" xmlns:xsl="[ignore][/ignore]">
<xsl:eek:utput method="text" omit-xml-declaration="yes" encoding="utf-8" />
<xsl:template match="/">
<xsl:apply-templates select="root" />
</xsl:template>
<xsl:template match="root">
<xsl:apply-templates select="field" />
</xsl:template>
<xsl:template match="field">
<xsl:variable name="fieldname" select="@name" />
<xsl:variable name="pv" select="position()" />
<xsl:for-each select="option">
<xsl:call-template name="proc-option">
<xsl:with-param name="origin" select="$fieldname" />
<xsl:with-param name="pv" select="$pv" />
<xsl:with-param name="linklist" select="$fieldname" />
</xsl:call-template>
</xsl:for-each>
</xsl:template>

<xsl:template name="proc-option">
<xsl:param name="origin" />
<xsl:param name="pv" />
<xsl:param name="linklist" />
<xsl:if test="not(contains($linklist,@name)) and (count(//field[@name=current()/@name]) > 0)">
<xsl:call-template name="proc-field">
<xsl:with-param name="origin" select="$origin" />
<xsl:with-param name="pv" select="$pv" />
<xsl:with-param name="field" select="//field[@name=current()/@name][1]" />
<xsl:with-param name="linklist" select="concat($linklist,'-',@name)" />
</xsl:call-template>
</xsl:if>
<xsl:if test="not(contains($linklist,@name)) and (count(//field[@name=current()/@name]) = 0)">
<xsl:value-of select="concat('field [',$pv,'] ',$origin,':path=>',$linklist,'-',@name,':stopped','&#x0a;')" />
</xsl:if>
<xsl:if test="contains($linklist,@name)">
<xsl:value-of select="concat('field [',$pv,'] ',$origin,':path=>',$linklist,'-',@name,':looping','&#x0a;')" />
</xsl:if>
</xsl:template>

<xsl:template name="proc-field">
<xsl:param name="origin" />
<xsl:param name="pv" />
<xsl:param name="field" />
<xsl:param name="linklist" />
<xsl:for-each select="$field/option">
<xsl:call-template name="proc-option">
<xsl:with-param name="origin" select="$origin" />
<xsl:with-param name="pv" select="$pv" />
<xsl:with-param name="linklist" select="$linklist" />
</xsl:call-template>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
[/tt]
[6] The output would look like this.
[tt]
field [1] a:path=>a-p-w:stopped
field [1] a:path=>a-p-b-r:stopped
field [1] a:path=>a-p-b-s-x:stopped
field [1] a:path=>a-p-b-s-y:stopped
field [1] a:path=>a-p-b-t:stopped
field [1] a:path=>a-p-p:looping
field [1] a:path=>a-p-a:looping
field [1] a:path=>a-q:stopped
field [2] b:path=>b-r:stopped
field [2] b:path=>b-s-x:stopped
field [2] b:path=>b-s-y:stopped
field [2] b:path=>b-t:stopped
field [3] p:path=>p-w:stopped
field [3] p:path=>p-b-r:stopped
field [3] p:path=>p-b-s-x:stopped
field [3] p:path=>p-b-s-y:stopped
field [3] p:path=>p-b-t:stopped
field [3] p:path=>p-p:looping
field [3] p:path=>p-a-p:looping
field [3] p:path=>p-a-q:stopped
field [4] s:path=>s-x:stopped
field [4] s:path=>s-y:stopped
[/tt]
[7] How and what do you get something out of the demo are up to you and your readiness to do with the technologies.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top