Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / XML / October 2006

Tip: Looking for answers? Try searching our database.

transforming attributes into elements

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jakub.Bednarczuk@gmail.com - 24 Oct 2006 14:49 GMT
Hallo everybody

I have the problem with getting attributes values and also attributes
names. I am reading an xml file with DOM. Lets see an example:

file I read
<root>
 <Def></Def>
 <Elements>
    <Element att1="1" att2="2" att3="3">    //Some attributes are
optional
    .......
 </Elements>
</root>

file I want to generate
<root>
 <module>
   <id>
       <att1></att1>
   </id>
   <def>
     <att2></att2>
   </def>
   <spec>
     <att3></att3>
   <spec>
</root>

I have the following code

XmlDocument doc = new XmlDocument();
doc.Load("filename");
XmlElement root = doc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("//Elements/Element/@att1");

foreach (XmlNode node in nodes){
 string attr = node.Value;
 module(some attributes);   //this method generate <module> than
}

module(){
 WriteStartElement("module");
 id();
 def();  // this methods are similar to this one
 spec();
 WriteEndElement()
}

So far I am able to take values only of one kind of attributes and
write them in output file.
My goal is to take all attributes of given element and depending on
which attribute is it give the value to appropriate output element.

Any idea how to solve it ?

Jakub Bednarczuk
Martin Honnen - 24 Oct 2006 15:10 GMT
> <root>
>   <Def></Def>
[quoted text clipped - 18 lines]
>     <spec>
> </root>

What about the attribute values (e.g. att1="1"), don't you want to copy
them?

Anyway, an XSLT stylesheet might do what you want but you need to
provide a precise specification. Do you have several |Element| elements?
Do you want to create one |module| element for each |Element| element?
Neither your example input (no closing </Element>) nor your example
output (no closing </spec>, no closing </module>) is well-formed so
anyone trying to help has to guess what you want to achieve.

For instance this stylesheet

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

<xsl:output method="xml" indent="yes"/>

<xsl:template match="root">
  <xsl:copy>
    <xsl:apply-templates select="Elements/Element"/>

  </xsl:copy>
</xsl:template>

<xsl:template match="Element">
  <module>
    <xsl:apply-templates select="@att1"/>
    <xsl:apply-templates select="@att2"/>
    <xsl:apply-templates select="@att3"/>
  </module>
</xsl:template>

<xsl:template match="@att1">
  <id>
    <att1><xsl:value-of select="."/></att1>
  </id>
</xsl:template>

<xsl:template match="@att2">
  <def>
    <att2><xsl:value-of select="."/></att2>
  </def>
</xsl:template>

<xsl:template match="@att3">
  <spec>
    <att2><xsl:value-of select="."/></att2>
  </spec>
</xsl:template>

</xsl:stylesheet>

applied to the well-formed input

<root>
  <Def></Def>
  <Elements>
     <Element att1="1" att2="2" att3="3"></Element>
  </Elements>
</root>

yields the result

<root>
  <module>
    <id>
      <att1>1</att1>
    </id>
    <def>
      <att2>2</att2>
    </def>
    <spec>
      <att2>3</att2>
    </spec>
  </module>
</root>

The stylesheet creates one |module| element for each |Element| element.

If you need help running a stylesheet with .NET check the documentation
of XslTransform in System.Xml.Xsl for .NET 1.x and of
XslCompiledTransform in System.Xml.Xsl for .NET 2.0. If the
documentation does not help then ask again but tell us which .NET
version you are using.

Signature

    Martin Honnen --- MVP XML
    http://JavaScript.FAQTs.com/

Jakub.Bednarczuk@gmail.com - 25 Oct 2006 09:29 GMT
Thanks a lot.
Now when I have a look on what I wrote down, I am little bit confused,
that I forgot to write down closing tags. Below I present corrected
input and outputfile. There is some additional elements which I also
forgot to write down (no idea what I was thinking about during posting
previous message).

input
<root>
 <Module>
    <Def></Def>
    <Elements>
       <Element att1="1" att2="2" att3="3"/>    // att3 is optional
     .......
    </Elements>
 </Module>
 //next modules
</root>

file I want to generate
<root>
  <Module>
    <Id>
        <att1></att1>
    </Id>
    <Def>
      <att2></att2>
    </Def>
    <Spec>
      <att3></att3>      //in input file att3 is optional, same here
<Spec> and att3 are optional
   </Spec>
 </Module>
 //next modules
</root>

The XSLT looks nice, but I need to do it with C#, because I will do
some additional transformation on these attributes. So far I have
little problem with placing them in appropraite elements. I am using
.NET 2.0

> > <root>
> >   <Def></Def>
[quoted text clipped - 105 lines]
> documentation does not help then ask again but tell us which .NET
> version you are using.
Jakub.Bednarczuk@gmail.com - 25 Oct 2006 09:30 GMT
Thanks a lot.
Now when I have a look on what I wrote down, I am little bit confused,
that I forgot to write down closing tags. Below I present corrected
input and outputfile. There is some additional elements which I also
forgot to write down (no idea what I was thinking about during posting
previous message).

input
<root>
 <Module>
    <Def></Def>
    <Elements>
       <Element att1="1" att2="2" att3="3"/>    // att3 is optional
     .......
    </Elements>
 </Module>
 //next modules
</root>

file I want to generate
<root>
  <Module>
    <Id>
        <att1></att1>
    </Id>
    <Def>
      <att2></att2>
    </Def>
    <Spec>
      <att3></att3>      //in input file att3 is optional, same here
<Spec> and att3 are optional
   </Spec>
 </Module>
 //next modules
</root>

The XSLT looks nice, but I need to do it with C#, because I will do
some additional transformation on these attributes. So far I have
little problem with placing them in appropraite elements. I am using
.NET 2.0

> > <root>
> >   <Def></Def>
[quoted text clipped - 105 lines]
> documentation does not help then ask again but tell us which .NET
> version you are using.
Jakub.Bednarczuk@gmail.com - 25 Oct 2006 09:42 GMT
I forgot to write what solution do I have so far

XmlDocument doc= new XmlDocument();
doc.Load("filename");

XmlElement root = doc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("//Elements/Element/@*");

foreach (XmlNode node in nodes)
                   {
string attr = node.Value;
method(attr);
WriteEndElement();
}

method(strong attr){
WriteStartElement("Uid");
WriteString(attr);
WriteEndElement();
}

methods has more attributes but here is not the case tpo write all of
them. Simply I would like to make some conditions where to place value
of each attribute. I mean that
XmlNodeList nodes = root.SelectNodes("//Elements/Element/@*");  takes
values of attributes but it doesnt store names of these attributes.
Simply I have no idea how to put attributes from one node to different
elements

Jakub.Bednarc...@gmail.com wrote:
> Thanks a lot.
> Now when I have a look on what I wrote down, I am little bit confused,
[quoted text clipped - 151 lines]
> >     Martin Honnen --- MVP XML
> >     http://JavaScript.FAQTs.com/
Martin Honnen - 25 Oct 2006 18:25 GMT
> input
> <root>
[quoted text clipped - 27 lines]
> The XSLT looks nice, but I need to do it with C#, because I will do
> some additional transformation on these attributes.

Here is C# DOM code

      XmlDocument xmlDocument = new XmlDocument();
      xmlDocument.Load(@"file.xml");
      foreach (XmlElement module in
xmlDocument.SelectNodes(@"/root/Module")) {
        foreach (XmlElement element in
module.SelectNodes(@"Elements/Element")) {
          element.ParentNode.RemoveChild(element);

          XmlElement id = xmlDocument.CreateElement("Id");
          XmlElement att1 = xmlDocument.CreateElement("att1");
          att1.InnerText = element.GetAttribute("att1");
          id.AppendChild(att1);
          module.InsertBefore(id, module.FirstChild);

          XmlElement att2 = xmlDocument.CreateElement("att2");
          att2.InnerText = element.GetAttribute("att2");
          module["Def"].AppendChild(att2);

          if (element.HasAttribute("att3")) {
            XmlElement spec = xmlDocument.CreateElement("Spec");
            XmlElement att3 = xmlDocument.CreateElement("att3");
            att3.InnerText = element.GetAttribute("att3");
            spec.AppendChild(att3);
            module.InsertAfter(spec, module["Def"]);
          }
        }
        module.RemoveChild(module["Elements"]);
      }

      xmlDocument.Save(Console.Out); // save to file here in real app
      Console.WriteLine();

The input

<root>
  <Module>
     <Def></Def>
     <Elements>
        <Element att1="1" att2="2" att3="3"/>
     </Elements>
  </Module>
</root>

ends up as

<root>
  <Module>
    <Id>
      <att1>1</att1>
    </Id>
    <Def>
      <att2>2</att2>
    </Def>
    <Spec>
      <att3>3</att3>
    </Spec>
  </Module>
</root>

That might or might not do what you want if there are several |Element|
elements but your description is still not clear to me. Nevertheless the
example should how how to create element nodes, how to remove nodes and
how to insert newly created nodes.

Signature

    Martin Honnen --- MVP XML
    http://JavaScript.FAQTs.com/

Jakub.Bednarczuk@gmail.com - 26 Oct 2006 08:57 GMT
Thanks a lot. I solved this problem yesterday in the afternoon, but
nevertheless thanks for help

> > input
> > <root>
[quoted text clipped - 93 lines]
> example should how how to create element nodes, how to remove nodes and
> how to insert newly created nodes.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.