17 #include "vtkCollection.h"
18 #include "vtkObjectFactory.h"
19 #include "vtkSmartPointer.h"
27 #if defined(_WIN32) && !defined(__CYGWIN__)
28 #define SNPRINTF _snprintf
30 #define SNPRINTF snprintf
33 struct vtkPVXMLElementInternals
35 std::vector<std::string> AttributeNames;
36 std::vector<std::string> AttributeValues;
37 typedef std::vector<vtkSmartPointer<vtkPVXMLElement> > VectorOfElements;
38 VectorOfElements NestedElements;
39 std::string CharacterData;
45 for (std::string::size_type cc = 0; cc < str.length(); ++cc)
47 if (!isspace(str[cc]))
62 this->Internal =
new vtkPVXMLElementInternals;
71 delete this->Internal;
77 this->Superclass::PrintSelf(os, indent);
78 os << indent <<
"Id: " << (this->
Id ? this->
Id :
"<none>") <<
endl;
79 os << indent <<
"Name: " << (this->
Name ? this->
Name :
"<none>") <<
endl;
81 for (
unsigned int i = 0; i < numNested; i++)
93 std::ostringstream valueStr;
94 valueStr << attrValue << ends;
101 std::ostringstream valueStr;
102 valueStr << attrValue << ends;
106 #if defined(VTK_USE_64BIT_IDS)
110 std::ostringstream valueStr;
111 valueStr << attrValue << ends;
119 std::ostringstream valueStr;
120 valueStr << attrValue << ends;
133 std::ostringstream valueStr;
134 valueStr << setprecision(precision) << attrValue << ends;
142 if (!attrName || !attrValue)
147 this->Internal->AttributeNames.push_back(attrName);
148 this->Internal->AttributeValues.push_back(attrValue);
154 if (!attrName || !attrValue)
160 size_t numAttributes = this->Internal->AttributeNames.size();
162 for (i = 0; i < numAttributes; ++i)
164 if (strcmp(this->Internal->AttributeNames[i].c_str(), attrName) == 0)
166 this->Internal->AttributeValues[i] = attrValue;
177 this->Internal->AttributeNames.clear();
178 this->Internal->AttributeValues.clear();
182 const char** attsIter = atts;
183 unsigned int count = 0;
188 unsigned int numberOfAttributes =
count / 2;
191 for (i = 0; i < numberOfAttributes; ++i)
201 this->Internal->NestedElements.clear();
207 std::vector<vtkSmartPointer<vtkPVXMLElement> >::iterator iter =
208 this->Internal->NestedElements.begin();
209 for (; iter != this->Internal->NestedElements.end(); ++iter)
211 if (iter->GetPointer() == element)
213 this->Internal->NestedElements.erase(iter);
223 for (
auto& elem : this->Internal->NestedElements)
225 if (elem.GetPointer() == elementToReplace)
246 this->Internal->NestedElements.push_back(element);
252 this->Internal->CharacterData.append(
data, length);
258 size_t numAttributes = this->Internal->AttributeNames.size();
260 for (i = 0; i < numAttributes; ++i)
262 if (strcmp(this->Internal->AttributeNames[i].c_str(),
name) == 0)
264 return this->Internal->AttributeValues[i].c_str();
272 return this->Internal->CharacterData.c_str();
284 os << indent <<
"<" << (this->
Name ? this->
Name :
"NoName");
285 size_t numAttributes = this->Internal->AttributeNames.size();
287 for (i = 0; i < numAttributes; ++i)
289 const char* aName = this->Internal->AttributeNames[i].c_str();
290 const char* aValue = this->Internal->AttributeValues[i].c_str();
296 os <<
" " << (aName ? aName :
"NoName") <<
"=\""
297 << (aValue ? sanitizedValue.c_str() :
"NoValue") <<
"\"";
299 size_t numberOfNestedElements = this->Internal->NestedElements.size();
300 bool hasCdata = !
vtkIsSpace(this->Internal->CharacterData);
302 bool childlessNode = (numberOfNestedElements == 0) && (hasCdata ==
false);
309 if (numberOfNestedElements > 0)
312 for (i = 0; i < numberOfNestedElements; ++i)
314 vtkIndent nextIndent = indent.GetNextIndent();
315 this->Internal->NestedElements[i]->PrintXML(os, nextIndent);
321 os << encoded.c_str();
322 os <<
"</" << (this->
Name ? this->
Name :
"NoName") <<
">\n";
326 os << indent <<
"</" << (this->
Name ? this->
Name :
"NoName") <<
">\n";
345 return static_cast<unsigned int>(this->Internal->NestedElements.size());
351 if (index < this->Internal->NestedElements.size())
353 return this->Internal->NestedElements[index];
367 size_t numberOfNestedElements = this->Internal->NestedElements.size();
369 for (i = 0; i < numberOfNestedElements; ++i)
371 const char* nid = this->Internal->NestedElements[i]->GetId();
372 if (nid && strcmp(nid,
id) == 0)
374 return this->Internal->NestedElements[i];
383 vtkPVXMLElementInternals::VectorOfElements::iterator iter =
384 this->Internal->NestedElements.begin();
385 for (; iter != this->Internal->NestedElements.end(); ++iter)
387 const char* cur_name = (*iter)->GetName();
388 if (
name && cur_name && strcmp(cur_name,
name) == 0)
407 const char* end = id;
408 while (*end && (*end !=
'.'))
410 unsigned int len = end - id;
411 char*
name =
new char[len + 1];
412 strncpy(
name,
id, len);
417 if (
next && (*end ==
'.'))
420 next =
next->LookupElementInScope(end + 1);
431 const char* end = id;
432 while (*end && (*end !=
'.'))
434 unsigned int len = end - id;
435 char*
name =
new char[len + 1];
436 strncpy(
name,
id, len);
442 while (curScope && !start)
447 if (start && (*end ==
'.'))
474 #if defined(VTK_USE_64BIT_IDS)
490 std::stringstream vstr;
493 for (i = 0; i < length; ++i)
522 #if defined(VTK_USE_64BIT_IDS)
559 vtkErrorMacro(
"elements cannot be NULL.");
564 vtkErrorMacro(
"name cannot be NULL.");
570 for (cc = 0; cc < numChildren; cc++)
573 if (child && child->GetName() && strcmp(child->GetName(),
name) == 0)
575 elements->AddItem(child);
581 for (cc = 0; cc < numChildren; cc++)
596 std::string sanitized =
"";
602 const char toescape[] = {
'&',
'\'',
'<',
'>',
'\"',
'\r',
'\n',
'\t', 0 };
604 size_t pt_length = strlen(plaintext);
605 sanitized.reserve(pt_length);
606 for (
size_t cc = 0; cc < pt_length; cc++)
608 const char* escape_char = toescape;
609 for (; *escape_char != 0; escape_char++)
611 if (plaintext[cc] == *escape_char)
620 SNPRINTF(temp, 20,
"&#x%x;",
static_cast<int>(*escape_char));
625 sanitized += plaintext[cc];
632 #if defined(VTK_USE_64BIT_IDS)
642 if (!element || 0 != strcmp(this->GetName(), element->GetName()))
649 const char* attr2 = element->
GetAttribute(attributeName);
650 if (attr1 && attr2 && 0 != strcmp(attr1, attr2))
657 if (!element->Internal->CharacterData.empty())
659 this->Internal->CharacterData = element->Internal->CharacterData;
663 size_t numAttributes = element->Internal->AttributeNames.size();
664 size_t numAttributes2 = this->Internal->AttributeNames.size();
666 for (
size_t i = 0; i < numAttributes; ++i)
669 for (
size_t j = 0; !found && j < numAttributes2; ++j)
671 if (element->Internal->AttributeNames[i] == this->Internal->AttributeNames[j])
673 this->Internal->AttributeValues[j] = element->Internal->AttributeValues[i];
680 this->
AddAttribute(element->Internal->AttributeNames[i].c_str(),
681 element->Internal->AttributeValues[i].c_str());
687 vtkPVXMLElementInternals::VectorOfElements::iterator iter;
688 vtkPVXMLElementInternals::VectorOfElements::iterator iter2;
690 for (iter = element->Internal->NestedElements.begin();
691 iter != element->Internal->NestedElements.end(); ++iter)
694 for (iter2 = this->Internal->NestedElements.begin();
695 iter2 != this->Internal->NestedElements.end(); ++iter2)
697 const char* attr1 = attributeName ? this->
GetAttribute(attributeName) :
NULL;
698 const char* attr2 = attributeName ? element->
GetAttribute(attributeName) :
NULL;
699 if (0 == strcmp((*iter)->Name, (*iter2)->Name) &&
700 (!attributeName || (!attr1 || !attr2 || 0 == strcmp(attr1, attr2))))
702 (*iter2)->Merge(*iter, attributeName);
710 newElement->SetName((*iter)->GetName());
711 newElement->SetId((*iter)->GetId());
712 newElement->Internal->AttributeNames = (*iter)->Internal->AttributeNames;
713 newElement->Internal->AttributeValues = (*iter)->Internal->AttributeValues;
715 newElement->Merge(*iter, attributeName);
723 other->SetName(GetName());
724 other->SetId(GetId());
725 other->Internal->AttributeNames = this->Internal->AttributeNames;
726 other->Internal->AttributeValues = this->Internal->AttributeValues;
728 this->Internal->CharacterData.c_str(),
static_cast<int>(this->Internal->CharacterData.size()));
731 vtkPVXMLElementInternals::VectorOfElements::iterator iter;
732 for (iter = this->Internal->NestedElements.begin(); iter != this->Internal->NestedElements.end();
736 (*iter)->CopyTo(newElement);
744 other->SetName(GetName());
745 other->SetId(GetId());
746 other->Internal->AttributeNames = this->Internal->AttributeNames;
747 other->Internal->AttributeValues = this->Internal->AttributeValues;
749 this->Internal->CharacterData.c_str(),
static_cast<int>(this->Internal->CharacterData.size()));
763 std::ostringstream selfstream;
764 std::ostringstream otherstream;
765 this->
PrintXML(selfstream, vtkIndent());
766 other->
PrintXML(otherstream, vtkIndent());
767 return (selfstream.str() == otherstream.str());
773 std::vector<std::string>::iterator nameIterator = this->Internal->AttributeNames.begin();
774 std::vector<std::string>::iterator valueIterator = this->Internal->AttributeValues.begin();
775 while (nameIterator != this->Internal->AttributeNames.end())
777 if (strcmp(nameIterator->c_str(),
name) == 0)
779 this->Internal->AttributeNames.erase(nameIterator);
780 this->Internal->AttributeValues.erase(valueIterator);
vtkPVXMLElement * GetParent()
unsigned int GetNumberOfNestedElements()
const char * GetCharacterData()
void PrintXML(ostream &os, vtkIndent indent)
int GetCharacterDataAsVector(int length, int *value)
void RemoveAllNestedElements()
void ReplaceNestedElement(vtkPVXMLElement *elementToReplace, vtkPVXMLElement *element)
int GetScalarAttribute(const char *name, int *value)
void PrintSelf(ostream &os, vtkIndent indent) override
~vtkPVXMLElement() override
vtkPVXMLElement * FindNestedElement(const char *id)
vtkPVXMLElement * LookupElementInScope(const char *id)
void AddNestedElement(vtkPVXMLElement *element, int setPrent)
const char * GetAttributeOrDefault(const char *name, const char *notFound)
void GetElementsByName(const char *name, vtkCollection *elements)
static std::string Encode(const char *plaintext)
void RemoveAttribute(const char *attrName)
vtkPVXMLElement * LookupElementUpScope(const char *id)
vtkPVXMLElement * LookupElement(const char *id)
vtkPVXMLElement * GetNestedElement(unsigned int index)
void AddCharacterData(const char *data, int length)
void ReadXMLAttributes(const char **atts)
bool Equals(vtkPVXMLElement *other)
void SetParent(vtkPVXMLElement *parent)
void AddAttribute(const char *attrName, const char *attrValue)
const char * GetAttribute(const char *name)
vtkPVXMLElement * FindNestedElementByName(const char *name)
void RemoveNestedElement(vtkPVXMLElement *)
int GetVectorAttribute(const char *name, int length, int *value)
void CopyAttributesTo(vtkPVXMLElement *other)
void Merge(vtkPVXMLElement *element, const char *attributeName)
void SetAttribute(const char *attrName, const char *attrValue)
void CopyTo(vtkPVXMLElement *other)
QTextStream & endl(QTextStream &stream)
static bool vtkIsSpace(const std::string &str)
vtkStandardNewMacro(vtkPVXMLElement)
int vtkPVXMLVectorAttributeParse(const char *str, int length, T *data)