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

output xml but in specified order

Status
Not open for further replies.

zalim30

Programmer
Oct 13, 2005
17
GB
hi there
I have two xml files and would like to generate a text file. The logic is
first.xml
<?xml version="1.0"?>
<source>
<object partid ="4" name = "def" price = "3000"/>
<object partid ="5" name = "jkl" price = "130"/>
<object partid ="1" name = "abc1" price = "0"/>
<object partid ="2" name = "def" price = "430"/>
<object partid ="3" name = "abc" price = "350"/>
<object partid ="4" name = "abc" price = "230"/>
</source>
-------------------second.xml------------------------------
<?xml version="1.0"?>
<order>
<attribute1 name= "price"/>
<attribute1 name= "name"/>
<attribute1 name= "partid"/>
</order>
______________________________________________________________
Now I want to write an xslt which will output the value of each attribute of the element object but in the order as specified by the second.xml...For example in this particular case...
the output should be ...
3000, def, 4
130, jkl, 5,
etc
Any ideas/help.
 
I have looked at this three times, and I find the problem statement confusing.

Certainly it would seem that you can do what you want (or what I think you want). Why don't you try building a XSLT and see if that helps clarify the problem statement somewhat.

Tom Morrison
 
Thanks Tom
Let me clarify it.
The file called first.xml contains the data. The file called second.xml contains the ordering information. I need to write an xslt that outputs the comma separated values of attributes of each element of first.xml in the order specified by second.xml.
for example the output would be...
3000, def, 4
130, jkl, 5,
..........so on
if second.xml is
<?xml version="1.0"?>
<order>
<attribute1 name= "price"/>
<attribute1 name= "name"/>
<attribute1 name= "partid"/>
</order>
_-----------------------------------------------------
And output would be
4,3000, def
5,130, jkl
...............
if the second.xml is


<?xml version="1.0"?>
<order>
<attribute1 name= "partid"/>
<attribute1 name= "price"/>
<attribute1 name= "name"/>
</order>

-------------------------------------------------
So we can change the order of attributes in second.xml and the result would be in different order.
I hope I clarified this time.
 
Here's one way of doing it:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]
  <xsl:output method="text"/>
  <xsl:template match="/">
    <xsl:apply-templates select="source/object"/>
  </xsl:template>
  <xsl:template match="object">
    <xsl:variable name="pos" select="position()"/>
    <xsl:for-each select="document('second.xml')/order/attribute1">
      <xsl:value-of select="document('first.xml')/source/object[$pos]/@*[name(.) = current()/@name]"/>
      <xsl:choose>
        <xsl:when test="following-sibling::node()">
          <xsl:text>,</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text disable-output-escaping="yes">&#010;</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Jon

"I don't regret this, but I both rue and lament it.
 
Great Jonty
I am trying your solution...
here is the one that I wrote..
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="
<xsl:eek:utput method="text"/>

<!-- xml_files to be used as input -->

<xsl:variable name="source" select="//input/@source" />
<xsl:variable name="order" select="//input/@order" />
<xsl:variable name="attribute_name" select="//input/@attribute_name" />
<xsl:variable name="tab" select="'&#09;'" />
<xsl:variable name="newline" select="'&#010;'" />
<xsl:variable name="attribute_list" select="document($order)//@*[name(.)='name'>

<!-- **************************** Template ************************* -->

<xsl:template match = "/" >


<xsl:for-each select='document($source)//source/object'>
<xsl:variable name="object_name" select='.' />
<xsl:for-each select='document($order)//@*[name(.)=$attribute_name]'>
<xsl:variable name="attribute_name" select="."/>
<xsl:value-of select="$object_name/@*[name(.)= $attribute_name]" />,</xsl:for-each>
<xsl:value-of select="$newline"/>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>
 
Thanks Jont! It is working fine. The only thing that remains is that I don't want a comma after the last attribute...how to do that?e.g.
x,200,item,
w,500,788,
w,444,ppp,

should be
x,200,item
w,500,788
w,444,ppp

i.e. no comma if it is the last attribute.
Thanks in advance
 
Are you using your solution or mine? Mine checks if <attribute1> has following-sibling, if not it will output newline instead of comma.

Jon

"I don't regret this, but I both rue and lament it.
 
No I am using your solution and it prints all values in one line. i.e. it does not go into the xsl:eek:therwise portion?
 
You are using those exact XML files you posted?

Are you viewing the actual output or are you viewing it in IE? Browsers will display it on one line because a newline in a browser is denoted by <br/> not &#010;

Jon

"I don't regret this, but I both rue and lament it.
 
yes, exactly the same files + i am using xalan parser that writes the output in output.txt
 
I'm doing it in XML spy and I get the correct output. Must be parser specific problem. Try playing around with the test="following-sibling::node()". What output do you get with:
Code:
......
<xsl:for-each select="document('second.xml')/order/attribute1">
  <xsl:value-of select="document('first.xml')/source/object[$pos]/@*[name(.) = current()/@name]"/>
  <xsl:copy-of select="following-sibling::node()"/>
  <xsl:choose>
    <xsl:when test="following-sibling::node()">
......

Jon

"I don't regret this, but I both rue and lament it.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top