Do not report error if empty text children or comments are found after the document root element is finished.

Added method to get the first child of an XmlElement.


git-svn-id: http://yate.null.ro/svn/yate/trunk@5383 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
andrei 2013-01-25 14:42:33 +00:00
parent 598981ef54
commit 658acd87c3
2 changed files with 42 additions and 6 deletions

View File

@ -1533,10 +1533,8 @@ XmlSaxParser::Error XmlDocument::addChild(XmlChild* child)
// Text outside root: ignore empty, raise error otherwise // Text outside root: ignore empty, raise error otherwise
XmlText* text = child->xmlText(); XmlText* text = child->xmlText();
if (text) { if (text) {
String tmp(text->getText()); if (text->onlySpaces()) {
tmp.trimSpaces(); m_beforeRoot.addChild(text);
if (!tmp) {
TelEngine::destruct(child);
return XmlSaxParser::NoError; return XmlSaxParser::NoError;
} }
Debug(DebugNote,"XmlDocument. Got text outside element [%p]",this); Debug(DebugNote,"XmlDocument. Got text outside element [%p]",this);
@ -1551,6 +1549,8 @@ XmlSaxParser::Error XmlDocument::addChild(XmlChild* child)
DDebug(DebugStub,"XmlDocument. Request to add xml element child to incomplete root [%p]",this); DDebug(DebugStub,"XmlDocument. Request to add xml element child to incomplete root [%p]",this);
return XmlSaxParser::NotWellFormed; return XmlSaxParser::NotWellFormed;
} }
if ((child->xmlText() && child->xmlText()->onlySpaces()) || child->xmlComment())
return m_afterRoot.addChild(child);
// TODO: check what xml we can add after the root or if we can add // TODO: check what xml we can add after the root or if we can add
// anything after an incomplete root // anything after an incomplete root
Debug(DebugStub,"XmlDocument. Request to add non element while having a root [%p]",this); Debug(DebugStub,"XmlDocument. Request to add non element while having a root [%p]",this);
@ -1581,6 +1581,7 @@ void XmlDocument::toString(String& dump, bool escape, const String& indent, cons
dump << origIndent; dump << origIndent;
m_root->toString(dump,escape,indent,origIndent); m_root->toString(dump,escape,indent,origIndent);
} }
m_afterRoot.toString(dump,escape,indent,origIndent);
} }
// Reset this XmlDocument. Destroys root and clear the others xml objects // Reset this XmlDocument. Destroys root and clear the others xml objects
@ -1588,6 +1589,7 @@ void XmlDocument::reset()
{ {
TelEngine::destruct(m_root); TelEngine::destruct(m_root);
m_beforeRoot.clearChildren(); m_beforeRoot.clearChildren();
m_afterRoot.clearChildren();
m_file.clear(); m_file.clear();
} }
@ -1606,6 +1608,7 @@ XmlSaxParser::Error XmlDocument::read(Stream& in, int* error)
} }
break; break;
} }
parser.completeText();
if (parser.error() != XmlSaxParser::NoError) { if (parser.error() != XmlSaxParser::NoError) {
DDebug(DebugNote,"XmlDocument error loading stream. Parser error %d '%s' [%p]", DDebug(DebugNote,"XmlDocument error loading stream. Parser error %d '%s' [%p]",
parser.error(),parser.getError(),this); parser.error(),parser.getError(),this);
@ -1633,6 +1636,7 @@ int XmlDocument::write(Stream& out, bool escape, const String& indent,
m_beforeRoot.toString(dump,escape,indent,origIndent); m_beforeRoot.toString(dump,escape,indent,origIndent);
if (m_root) if (m_root)
m_root->toString(dump,escape,indent,origIndent,completeOnly); m_root->toString(dump,escape,indent,origIndent,completeOnly);
m_afterRoot.toString(dump,escape,indent,origIndent);
return out.writeData(dump); return out.writeData(dump);
} }
@ -1813,6 +1817,13 @@ const String& XmlElement::getText()
return txt ? txt->getText() : String::empty(); return txt ? txt->getText() : String::empty();
} }
XmlChild* XmlElement::getFirstChild()
{
if (!m_children.getChildren().skipNull())
return 0;
return static_cast<XmlChild*>(m_children.getChildren().skipNull()->get());
}
// Add a text child // Add a text child
void XmlElement::addText(const char* text) void XmlElement::addText(const char* text)
{ {
@ -2169,6 +2180,19 @@ void XmlText::toString(String& dump, bool esc, const String& indent,
dump << m_text; dump << m_text;
} }
bool XmlText::onlySpaces()
{
if (!m_text)
return true;
const char *s = m_text;
unsigned int i = 0;
for (;i < m_text.length();i++) {
if (s[i] == ' ' || s[i] == '\t' || s[i] == '\v' || s[i] == '\f' || s[i] == '\r' || s[i] == '\n')
continue;
return false;
}
return true;
}
/* /*
* XmlDoctype * XmlDoctype

View File

@ -1085,6 +1085,7 @@ private:
XmlElement* m_root; // The root element XmlElement* m_root; // The root element
XmlFragment m_beforeRoot; // XML children before root (declaration ...) XmlFragment m_beforeRoot; // XML children before root (declaration ...)
String m_file; // The file name used on load String m_file; // The file name used on load
XmlFragment m_afterRoot; // XML children after root (comments, empty text)
}; };
@ -1312,7 +1313,7 @@ public:
const String* auth = 0) const; const String* auth = 0) const;
/** /**
* Find the first child of this XmlElement * Find the first XmlElement child of this XmlElement
* @param name Optional name of the child * @param name Optional name of the child
* @param ns Optional child namespace * @param ns Optional child namespace
* @param noPrefix True to compare the tag without namespace prefix, false to * @param noPrefix True to compare the tag without namespace prefix, false to
@ -1325,7 +1326,7 @@ public:
{ return XmlFragment::findElement(getChildren().skipNull(),name,ns,noPrefix); } { return XmlFragment::findElement(getChildren().skipNull(),name,ns,noPrefix); }
/** /**
* Finds next child of this XmlElement * Finds next XmlElement child of this XmlElement
* @param prev Previous child * @param prev Previous child
* @param name Optional name of the child * @param name Optional name of the child
* @param ns Optional child namespace * @param ns Optional child namespace
@ -1357,6 +1358,12 @@ public:
return c ? &(c->getText()) : 0; return c ? &(c->getText()) : 0;
} }
/**
* Get first XmlChild of this XmlElement
* @return The first XmlChild found.
*/
XmlChild* getFirstChild();
/** /**
* @return The first XmlText found in this XmlElement children * @return The first XmlText found in this XmlElement children
*/ */
@ -1707,6 +1714,11 @@ public:
virtual XmlText* xmlText() virtual XmlText* xmlText()
{ return this; } { return this; }
/**
* Helper method to check if the text held by this XmlText contains only spaces
* @return False if the text contains non space characters.
*/
bool onlySpaces();
private: private:
String m_text; // The text String m_text; // The text
}; };