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

Converting XML elements to attributes

Hi there!

I am trying to convert the elements of an XML to attributes.

For example, the original XML looks like

<?xml version="1.0" encoding="ISO8859-1" ?>
<CATALOG>
  <CD>
    <TITLE>Empire Burlesque</TITLE>
    <ARTIST>Bob Dylan</ARTIST>
    <COUNTRY>USA</COUNTRY>
    <COMPANY>Columbia</COMPANY>
    <PRICE>10.90</PRICE>
    <YEAR>1985</YEAR>
  </CD>
  <CD>
    <TITLE>Hide your heart</TITLE>
    <ARTIST>Bonnie Tylor</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>CBS Records</COMPANY>
    <PRICE>9.90</PRICE>
    <YEAR>1988</YEAR>
  </CD>
 I need the final one to look like:

"<CD TITLE="Empire Burlesque" ARTIST="Bob Dylan" COUNTRY="USA" COMPANY="Columbia" PRICE="10.90" YEAR="1985"></CD>
<CD TITLE ="Hide your heart" .. and so on"

I am using the following ASP:
<%
'Load the XML
set xml = Server.CreateObject("Microsoft.XMLDOM")
xml.async = false
xml.load(Server.MapPath("cd_catalog.xml"))

'Load the XSL
set xsl = Server.CreateObject("Microsoft.XMLDOM")
xsl.async = false
xsl.load(Server.MapPath("cd_catalog.xsl"))

Response.Write(xml.transformNode(xsl))
%>

And XSL:
<?xml version=`1.0`?>
   xmlns:xsl="http://www.w3.org/XSL/Transform/1.0";
   default-space="strip"
   indent-result="yes">
 <xsl:template match="*">
 <xsl:copy>
 <xsl:for-each select="CD">
 <xsl:attribute name="{name(.)}"><xsl:value-of select="."/>
 </xsl:attribute>
 </xsl:for-each>
 <xsl:apply-templates select="*[* or @*]|text()"/>
 </xsl:copy>
 </xsl:template>
 </xsl:stylesheet>

But I get the following error:
"msxml3.dll error '80004005'

The stylesheet does not contain a document element. The stylesheet may be empty, or it may not be a well-formed XML document.

/xsl/convert.asp, line 12"

Does anyone know what's wrong in the above code? Or do you happen to have another method to convert XML elements to attributes using either ASP or PHP and of course XSL?

Thank you,
Mircea
0
mircea_a
Asked:
mircea_a
  • 2
1 Solution
 
Geert BormansCommented:
Hi Mircea,

It is generally not a good idea to test your XSLT directly in an ASP.
You should use a development environment for that
(I use Oxygen, www.oxygenxml.com and Stylus Studio, www.stylustudio.com)

The error message you get is because the stylesheet is not loaded in the stylesheet object.
The reason for that could be
- the stylesheet is not found at the location given
- the stylesheet is not valid

Your stylesheet has quiet some errors, so there is the reason
to name a few
- the XML declaration should have quotes around the version, or single quotes, not the fancy ones you use
- you need a stylesheet element
- strip-space is an element
- indent should be in the xsl:output element
-...

having corrected that, your stylesheet will not work either
I created a generic solution for your problem, that helps in this case

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output  indent="yes" />
<xsl:strip-space elements="*"/>
    <xsl:template match="node()[*[not(*)]]">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:for-each select="*">
                <xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
   <xsl:template match="node()">
       <xsl:copy>
           <xsl:copy-of select="@*"/>
           <xsl:apply-templates select="node() | text()"/>
       </xsl:copy>
   </xsl:template>
   </xsl:stylesheet>

I have two templates
- One for elements whoms children don't have children (that is the one above leaf element, you can attributize)
- one fallback for the other elements

I just did this this morning. I am convinced you can find more robust solutions out there
But this one will work for you

Cheers!
0
 
mircea_aAuthor Commented:
Hi Gertone!

Thanks for your answer, this is very helpful.

But, I really need to make it work from the ASP, or php.

I have replaced my xsl with the one you provided and now I get the following error:
"Switch from current encoding to specified encoding not supported. Error processing resource 'http://localhost/xsl/convert.a..."

I think that the ASP has a different encoding than the XML, and I've been trying to find a solution but no success so far. Do you have any idea on how to make that xsl work through the asp?

Thanks again,
Mircea
0
 
rdcproCommented:
Note the change to the ProgID:

<%
'Load the XML
set xml = Server.CreateObject("Msxml2.DomDocument")
xml.async = false
xml.load(Server.MapPath("cd_catalog.xml"))

'Load the XSL
set xsl = Server.CreateObject("Msxml2.DomDocument")
xsl.async = false
xsl.load(Server.MapPath("cd_catalog.xsl"))

' This transforms directly to the response stream, using the IStream interface.  It will preserve encoding
xml.transformNodeToObject(xsl, Response)
%>

You can modify the xsl:output statement in the XSLT to specify the same encoding you're using on your ASP page.

      <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

Regards,
Mike Sharp
0
 
Geert BormansCommented:
Mircea,

> But, I really need to make it work from the ASP, or php.

yes, I was not saying you should leave ASP
I was suggesting that you test the XSLT _before_ you plug it in an ASP.
After you know it works

> Switch from current encoding to specified encoding not supported

well, I have some observations
- the encoding in your source might not be accepted or well understood by the msxml parser you are using
the standardised encoding name for latin1 is <?xml version="1.0" encoding="ISO-8859-1" ?>
(note the extra '-')
I am not sure it would make a difference... but try it

- you could add an output encoding in the XSLT
change this line: <xsl:output  indent="yes" encoding="ISO-8859-1" />

- in order to have the output encoding working, you should use the IStream interface for your output
let us first see that the two earlier points don't help

- you are using the old MicroSoft objects
Server.CreateObject("Microsoft.XMLDOM")
you should use the version 2 objects "Msxml2.DomDocument.4.0" or "Msxml2.DomDocument" if you don't want to bind to a specific version

keep me posted

cheers
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

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