/// <summary> /// Sets an attribute of name to a given value. The attribute will be created if it does not exist, or changed if it does. /// </summary> public void SetAttribute(string cname, string cvalue) { TiXmlAttribute node = attributeSet.Find(cname); if (node != null) { node.SetValue(cvalue); return; } TiXmlAttribute attrib = new TiXmlAttribute(cname, cvalue); if (attrib != null) { attributeSet.Add(attrib); } else { TiXmlDocument document = GetDocument(); if (document != null) { document.SetError(ErrorType.TIXML_ERROR_OUT_OF_MEMORY, null, 0, null, TiXmlEncoding.TIXML_ENCODING_UNKNOWN); } } }
public override int Parse(string p, int index, TiXmlParsingData data, int encoding) { value = ""; TiXmlDocument document = GetDocument(); if (data != null) { data.Stamp(p, index, encoding); location = data.Cursor(); } const string startTag = "<![CDATA["; const string endTag = "]]>"; if (cdata || StringEqual(p, index, startTag, false, encoding)) { StringBuilder _value = new StringBuilder(); cdata = true; if (!StringEqual(p, index, startTag, false, encoding)) { document.SetError(ErrorType.TIXML_ERROR_PARSING_CDATA, p, index, data, encoding); return(INVALID_STRING_INDEX); } index += startTag.Length; // Keep all the white space, ignore the encoding, etc. while (index >= 0 && index < p.Length && !StringEqual(p, index, endTag, false, encoding)) { //value += p[index]; _value.Append(p[index]); ++index; } value = _value.ToString(); StringBuilder dummy = _value; index = ReadText(p, index, dummy, false, endTag, false, encoding); return(index); } else { StringBuilder _value = new StringBuilder(); bool ignoreWhite = true; string end = "<"; index = ReadText(p, index, _value, ignoreWhite, end, false, encoding); value = _value.ToString(); if (index >= 0) { return(index - 1); // don't truncate the '<' } return(INVALID_STRING_INDEX); } }
// [internal use] public override TiXmlNode Clone() { TiXmlDocument clone = new TiXmlDocument(); if (clone == null) { return(null); } CopyTo(clone); return(clone); }
public override int Parse(string p, int index, TiXmlParsingData data, int encoding) { TiXmlDocument document = GetDocument(); index = SkipWhiteSpace(p, index, encoding); if (data != null) { data.Stamp(p, index, encoding); location = data.Cursor(); } //if ( !p || !*p || *p != '<' ) if (index < 0 || index >= p.Length || p[index] != '<') { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_PARSING_UNKNOWN, p, index, data, encoding); } return(0); } ++index; value = ""; StringBuilder _value = new StringBuilder(); //while ( p && *p && *p != '>' ) while (index >= 0 && index < p.Length && p[index] != '>') { //value += p[index]; _value.Append(p[index]); ++index; } if (index < 0) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_PARSING_UNKNOWN, null, 0, null, encoding); } return(INVALID_STRING_INDEX); } value = _value.ToString(); if (p[index] == '>') { return(index + 1); } return(index); }
private void CopyTo(TiXmlDocument target) { base.CopyTo(target); target.error = error; target.errorId = errorId; target.errorDesc = errorDesc; target.tabsize = tabsize; target.errorLocation = errorLocation.Clone(); target.useMicrosoftBOM = useMicrosoftBOM; TiXmlNode node = null; for (node = firstChild; node != null; node = node.NextSibling()) { target.LinkEndChild(node.Clone()); } }
public override bool VisitExit(TiXmlDocument doc) { return(true); }
/// <summary> /// [internal use] /// Set the document pointer so the attribute can report errors. /// </summary> public void SetDocument(TiXmlDocument doc) { document = doc; }
public TiXmlDocument(TiXmlDocument copy) : base(TiXmlNode.NodeType.DOCUMENT) { copy.CopyTo(this); }
/// <summary> /// [internal use] /// Reads the "value" of the element -- another element, or text. /// This should terminate with the current end tag. /// </summary> protected int ReadValue(string p, int index, TiXmlParsingData data, int encoding) { TiXmlDocument document = GetDocument(); // Read in text and elements in any order. int pWithWhiteSpace = index; index = SkipWhiteSpace(p, index, encoding); while (index >= 0 && index < p.Length) { if (p[index] != '<') { // Take what we have, make a text element. TiXmlText textNode = new TiXmlText(""); if (textNode == null) { if (document == null) { document.SetError(ErrorType.TIXML_ERROR_OUT_OF_MEMORY, null, 0, null, encoding); } return(INVALID_STRING_INDEX); } if (IsWhiteSpaceCondensed()) { index = textNode.Parse(p, index, data, encoding); } else { // Special case: we want to keep the white space // so that leading spaces aren't removed. index = textNode.Parse(p, pWithWhiteSpace, data, encoding); } if (!textNode.Blank()) { LinkEndChild(textNode); } //else // delete textNode; } else { // We hit a '<' // Have we hit a new element or an end tag? This could also be // a TiXmlText in the "CDATA" style. if (StringEqual(p, index, "</", false, encoding)) { return(index); } else { TiXmlNode node = Identify(p, index, encoding); if (node != null) { index = node.Parse(p, index, data, encoding); LinkEndChild(node); } else { return(-1); } } } pWithWhiteSpace = index; index = SkipWhiteSpace(p, index, encoding); } if (index < 0) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_READING_ELEMENT_VALUE, null, 0, null, encoding); } } return(index); }
/* Attribtue parsing starts: next char past '<' * returns: next char past '>' */ public override int Parse(string p, int index, TiXmlParsingData data, int encoding) { index = SkipWhiteSpace(p, index, encoding); TiXmlDocument document = GetDocument(); if (p == null || index < 0 || index >= p.Length) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_PARSING_ELEMENT, null, 0, null, encoding); } return(0); } if (data != null) { data.Stamp(p, index, encoding); location = data.Cursor(); } if (p[index] != '<') { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_PARSING_ELEMENT, p, index, data, encoding); } return(0); } index = SkipWhiteSpace(p, index + 1, encoding); // Read the name. int pErr = index; index = ReadName(p, index, ref value, encoding); if (index < 0 || index >= p.Length) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, p, pErr, data, encoding); } return(INVALID_STRING_INDEX); } string endTag = "</"; endTag += value; endTag += ">"; // Check for and read attributes. Also look for an empty // tag or an end tag. while (index >= 0 && index < p.Length) { pErr = index; index = SkipWhiteSpace(p, index, encoding); if (index < 0 || index >= p.Length) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_READING_ATTRIBUTES, p, pErr, data, encoding); } return(-1); } if (p[index] == '/') { ++index; // Empty tag. if (p[index] != '>') { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_PARSING_EMPTY, p, index, data, encoding); } return(0); } return(index + 1); } else if (p[index] == '>') { // Done with attributes (if there were any.) // Read the value -- which can include other // elements -- read the end tag, and return. ++index; index = ReadValue(p, index, data, encoding); // Note this is an Element method, and will set the error if one happens. if (index < 0 || index >= p.Length) { // We were looking for the end tag, but found nothing. // Fix for [ 1663758 ] Failure to report error on bad XML if (document != null) { document.SetError(ErrorType.TIXML_ERROR_READING_END_TAG, p, index, data, encoding); } return(INVALID_STRING_INDEX); } // We should find the end tag now if (StringEqual(p, index, endTag, false, encoding)) { index += endTag.Length; return(index); } else { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_READING_END_TAG, p, index, data, encoding); } return(INVALID_STRING_INDEX); } } else { // Try to read an attribute: TiXmlAttribute attrib = new TiXmlAttribute(); if (attrib == null) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_OUT_OF_MEMORY, p, pErr, data, encoding); } return(-1); } attrib.SetDocument(document); pErr = index; index = attrib.Parse(p, index, data, encoding); if (index < 0 || index >= p.Length) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_PARSING_ELEMENT, p, pErr, data, encoding); } //delete attrib; return(INVALID_STRING_INDEX); } // Handle the strange case of double attributes: TiXmlAttribute node = attributeSet.Find(attrib.Name()); if (node != null) { node.SetValue(attrib.Value()); //delete attrib; return(INVALID_STRING_INDEX); } attributeSet.Add(attrib); } } return(index); }
/// <summary> /// Figure out what is at *p, and parse it. Returns null if it is not an xml node. /// </summary> protected TiXmlNode Identify(string p, int index, int encoding) { TiXmlNode returnNode = null; index = SkipWhiteSpace(p, index, encoding); if (p == null || index < 0 || index >= p.Length || p[index] != '<') { return(null); } TiXmlDocument doc = GetDocument(); index = SkipWhiteSpace(p, index, encoding); if (index < 0 || index >= p.Length) { return(null); } // What is this thing? // - Elements start with a letter or underscore, but xml is reserved. // - Comments: <!-- // - Decleration: <?xml // - Everthing else is unknown to tinyxml. // const string xmlHeader = "<?xml"; const string commentHeader = "<!--"; const string dtdHeader = "<!"; const string cdataHeader = "<![CDATA["; if (StringEqual(p, index, xmlHeader, true, encoding)) { #if UNUSED TIXML_LOG("XML parsing Declaration\n"); #endif returnNode = new TiXmlDeclaration(); } else if (StringEqual(p, index, commentHeader, false, encoding)) { #if UNUSED TIXML_LOG("XML parsing Comment\n"); #endif returnNode = new TiXmlComment(); } else if (StringEqual(p, index, cdataHeader, false, encoding)) { #if UNUSED TIXML_LOG("XML parsing CDATA\n"); #endif TiXmlText text = new TiXmlText(""); text.SetCDATA(true); returnNode = text; } else if (StringEqual(p, index, dtdHeader, false, encoding)) { #if UNUSED TIXML_LOG("XML parsing Unknown(1)\n"); #endif returnNode = new TiXmlUnknown(); } else if (IsAlpha(p[index + 1], encoding) || p[index + 1] == '_') { #if UNUSED TIXML_LOG("XML parsing Element\n"); #endif returnNode = new TiXmlElement(""); } else { #if UNUSED TIXML_LOG("XML parsing Unknown(2)\n"); #endif returnNode = new TiXmlUnknown(); } if (returnNode != null) { // Set the parent, so it can report errors returnNode.parent = this; } else { if (doc != null) { doc.SetError(ErrorType.TIXML_ERROR_OUT_OF_MEMORY, null, 0, null, TiXmlEncoding.TIXML_ENCODING_UNKNOWN); } } return(returnNode); }
/// <summary> /// Visit a document. /// </summary> public virtual bool VisitExit(TiXmlDocument doc) { return(true); }
public override int Parse(string p, int index, TiXmlParsingData data, int _encoding) { index = SkipWhiteSpace(p, index, _encoding); // Find the beginning, find the end, and look for // the stuff in-between. TiXmlDocument document = GetDocument(); if (index < 0 || index >= p.Length || !StringEqual(p, index, "<?xml", true, _encoding)) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_PARSING_DECLARATION, null, 0, null, _encoding); } return(INVALID_STRING_INDEX); } if (data != null) { data.Stamp(p, index, _encoding); location = data.Cursor(); } p += 5; version = ""; encoding = ""; standalone = ""; while (index >= 0 && index < p.Length) { if (p[index] == '>') { ++index; return(index); } index = SkipWhiteSpace(p, index, _encoding); if (StringEqual(p, index, "version", true, _encoding)) { TiXmlAttribute attrib = new TiXmlAttribute(); index = attrib.Parse(p, index, data, _encoding); version = attrib.Value(); } else if (StringEqual(p, index, "encoding", true, _encoding)) { TiXmlAttribute attrib = new TiXmlAttribute(); index = attrib.Parse(p, index, data, _encoding); encoding = attrib.Value(); } else if (StringEqual(p, index, "standalone", true, _encoding)) { TiXmlAttribute attrib = new TiXmlAttribute(); index = attrib.Parse(p, index, data, _encoding); standalone = attrib.Value(); } else { // Read over whatever it is. while (index >= 0 && index < p.Length && p[index] != '>' && !IsWhiteSpace(p[index])) { ++index; } } } return(INVALID_STRING_INDEX); }
/* Attribute parsing starts: at the ! of the !-- * returns: next char past '>' */ public override int Parse(string p, int index, TiXmlParsingData data, int encoding) { TiXmlDocument document = GetDocument(); value = ""; index = SkipWhiteSpace(p, index, encoding); if (data != null) { data.Stamp(p, index, encoding); location = data.Cursor(); } const string startTag = "<!--"; const string endTag = "-->"; if (!StringEqual(p, index, startTag, false, encoding)) { document.SetError(ErrorType.TIXML_ERROR_PARSING_COMMENT, p, index, data, encoding); return(INVALID_STRING_INDEX); } index += startTag.Length; // [ 1475201 ] TinyXML parses entities in comments // Oops - ReadText doesn't work, because we don't want to parse the entities. // p = ReadText( p, &value, false, endTag, false, encoding ); // // from the XML spec: /* * [Definition: Comments may appear anywhere in a document outside other markup; in addition, * they may appear within the document type declaration at places allowed by the grammar. * They are not part of the document's character data; an XML processor MAY, but need not, * make it possible for an application to retrieve the text of comments. For compatibility, * the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity * references MUST NOT be recognized within comments. * * An example of a comment: * * <!-- declarations for <head> & <body> -. */ value = ""; StringBuilder _value = new StringBuilder(); // Keep all the white space. //while ( p && *p && !StringEqual( p, endTag, false, encoding ) ) while (index >= 0 && index < p.Length && !StringEqual(p, index, endTag, false, encoding)) { _value.Append(p, index, 1); ++index; } if (index >= 0 && index < p.Length) { index += endTag.Length; } value = _value.ToString(); return(index); }