[xsd-users] Arbitrary XML inside XML element
Boris Kolpackov
boris at codesynthesis.com
Fri Aug 8 12:33:06 EDT 2008
Hi Attila,
Attila <atteeela at gmail.com> writes:
> Now I would want a way to retrieve all "skipped" content underneath the
> <message> element as a string. I do not want callbacks on each any'ed
> element (as I have indicated I want to skip processing the contents).
processContent="skip" in XML Schema means that the content will not be
validated, not that it won't be accessible to the application (e.g., in
DOM or SAX). Furthermore, it is not possible for an XML parser to really
skip a chunk of document since it needs to parse it in order to determine
where to stop skipping (i.e., it needs to detect the closing tag of a
fragment you want skipped).
> XML Instance:
>
> <message>
> <to>a</to>
> <from>b</from>
> <subject>c</subject>
> <myElement>
> <asdf>...</asdf>
> </myElement>
> </message
>
> Would there be a way for me to retrieve:
>
> <myElement>
> <asdf>...</asdf>
> </myElement>
>
> As text when processing <message>?
The parser will deliver this fragment as raw SAX callbacks which
you can override to construct an XML string from it. For example:
struct message_pimpl: message_pskel
{
message_pimpl ()
: depth_ (0)
{
}
virtual void
_start_any_element (const xml_schema::ro_string& ns,
const xml_schema::ro_string& name,
const xml_schema::ro_string* type)
{
if (depth_ == 0)
{
start_tag_ = false;
wildcard_content_.clear ();
}
if (start_tag_)
wildcard_content_ += ">"; // Close previous start tag.
wildcard_content_ += "<";
wildcard_content_ += name;
start_tag_ = true;
depth_++;
}
virtual void
_any_attribute (const xml_schema::ro_string& ns,
const xml_schema::ro_string& name,
const xml_schema::ro_string& value)
{
wildcard_content_ += " ";
wildcard_content_ += name;
wildcard_content_ += "=\"";
wildcard_content_ += value;
wildcard_content_ += "\"";
}
virtual void
_end_any_element (const xml_schema::ro_string& ns,
const xml_schema::ro_string& name)
{
if (start_tag_)
{
wildcard_content_+= "/>" // Empty content element.
start_tag_ = false;
}
else
{
wildcard_content_ += "</";
wildcard_content_ += name;
wildcard_content_ += ">";
}
depth_--;
}
virtual void
_any_characters (const ro_string& s)
{
if (start_tag_)
{
wildcard_content_ += ">"; // Close previous start tag.
start_tag_ = false;
}
wildcard_content_ += s;
}
private:
size_t depth_;
bool start_tag_;
string wildcard_content_;
};
Boris
More information about the xsd-users
mailing list