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 Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Combining elements 1

Status
Not open for further replies.

bjmurph

Programmer
Mar 2, 2007
4
CA
Hello,

I was wondering if someone could help me combine elements within an xml file, giving priority to a specific element depending on the attribute. For instance, the initial file looks like this:
===
<content>
<pages>
<page idl="/index_en" label="Home" position="1" tags=""/>
<page idl="/news_en" label="News" position="2" tags=""""/>
<page idl="/news/sample_en" label="Sample Story" position="3" tags=""news""/>
<page idl="/test_en" label="Test Page" position="4" tags=""/>
</pages>

<files>
<file idl="/index_en" tags="home"/>
<file idl="/news_en" tags="news"/>
<file idl="/news/sample_en" tags=""news""/>
<file idl="/test_en" tags=""/>
</files>
</content>
===
And I'm trying to get an output similar to:
===
<pages>
<page idl="/index_en" label="Home" position="1" tags="home"/>
<page idl="/news_en" label="News" position="2" tags=""news""/>
<page idl="/news/sample_en" label="Sample Story" position="3" tags=""news""/>
<page idl="/test_en" label="Test Page" position="4" tags=""/>
</pages>
===

So, I need it to search and find the matching file and page attributes (that have the same idl), then combine them into a new page element. Having said that, I want the "label" attribute to come from the original page element and the tag attribute to come from the original file element.
If anyone has some advise it would be appreciated.
 
This is easily accomplished using XSLT. You may find a tutorial on XSLT here.

Here is a partial solution. You can fill in additional details.
Code:
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]

<xsl:template match="/">
<content>
<pages>
	<xsl:for-each select="content/pages/page">
	<xsl:variable name="myidl" select="@idl"/>
	<page>
		<xsl:attribute name="idl">
			<xsl:value-of select="$myidl"/>
		</xsl:attribute>
		<xsl:attribute name="tags">
			<xsl:value-of select="/content/files/file[@idl = $myidl]/@tags"/>
		</xsl:attribute>
	</page>
	</xsl:for-each>
</pages>
</content>
</xsl:template>

</xsl:stylesheet>
Code:
<content>
  <pages>
    <page idl="/index_en" tags="home"/>
    <page idl="/news_en" tags="news"/>
    <page idl="/news/sample_en" tags="news"/>
    <page idl="/test_en" tags=""/>
  </pages>
</content>



Tom Morrison
 
Tom,

The tutorial you referenced states:
Note: Once you have set a variable's value, you cannot change or modify that value!
Since you are setting the value of myidl within the "for-each", does that mean you are changing the value of myidl for each page? I thought the value of myidl cannot change after it is set the first time, so why does this work?


- Dan
 
The variable goes in and out of scope, so it is not really the same variable.

You can consider the closing </xsl:for-each> as the processing instruction (I know it isn't but...) which throws away all the trash from the iteration. This goes hand-in-hand with the fact that, within the scope of the <xsl:for-each>, the context node (i.e. the 'current node' within the input document) changes on each iteration, and is not the same as the context outside the <xsl:for-each>. The variable declared within the context of the <xsl:for-each> is not available outside that context.

Does this explain it?

Oh...and the answer to your question is, "yes, sort of."



Tom Morrison
 
Thanks Tom. That explains it. I did not realize the scope in a for-each worked that way. Good to know.
 
Hi Tom, thank you for the help and apologize for delay in my reply. Your method worked perfectly.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top