[xsde-users] Get the currently parsed element's name

Boris Kolpackov boris at codesynthesis.com
Wed Oct 29 02:32:49 EDT 2008


Hi Khuong,

Khuong Nguyen Thi Lien <ntlkhuong at tma.com.vn> writes:

> Thanks for you response, with the technique pointed out in [1], we can
> retrieve the name of the child element which is supposed to be successively
> parsed, my current situation is we want to retrieve the current element name
> when the parser is processing on it. This could help us to create the object
> with the name of the current element and return to the parent element.

I understand now. There is no built-in support for this. In fact,
some types (i.e., simple types) can be used for both elements and
attributes. I see two ways to achieve what you want. Let's say we
have the following schema:

<complexType name="inner">
  <sequence>

    ...

  </sequence>
</complexType>

<complexType name="outer">
  <sequence>
    <element name="x" type="inner"/>
  </sequence>
</complexType>

Here we want to know the name of the element that is being parsed
('x' in our case) in the inner_pimpl parser implementation. With
the first approach you simply establish a connection between
inner_pimpl and outer_pimpl and use the same approach in
outer_pimpl as described previously:

struct inner_pimpl: inner_pskel
{
  inner_pimpl (const string& element_name)
    : element_name_ (element_name)
  {
  }

  virtual void
  pre ()
  {
    // element_name_ contains the element name we are parsing.
  }

private:
  const string& element_name_;
};

struct outer_pimpl: outer_pskel
{
  virtual void
  _start_element (const xml_schema::ro_string& ns,
                  const xml_schema::ro_string& name
                  const char* type)
  {
     element_name_ = name;

     // Always call the base _start_element().
     //
     outer_pskel::_start_element (ns, name, type);
  }

public:
  string element_name_;
};


Then, when you create your parsers, you establish the connection:

outer_pimpl outer_p;
inner_pimpl inner_p (outer_p.element_name_);

The second approach works best if you are passing the object from
inner_pimpl to outer_pimpl. Let's say we have the inner_t C++ type
corresponding to the inner XML Schema type:

struct inner_t
{
  ...

  string element_name_;
};

The idea is to set the element name in outer_pimpl:

struct inner_pimpl: inner_pskel
{
  virtual inner_t*
  post_inner ()
  {
    return new inner_t;
  }
};

struct outer_pimpl: outer_pskel
{
  virtual void
  x (inner_t* i)
  {
    i->element_name_ = element_name_; 
  }

  virtual void
  _start_element (const xml_schema::ro_string& ns,
                  const xml_schema::ro_string& name
                  const char* type)
  {
     element_name_ = name;

     // Always call the base _start_element().
     //
     outer_pskel::_start_element (ns, name, type);
  }

public:
  string element_name_;
};

Boris



More information about the xsde-users mailing list