mirror of
				https://github.com/Telecominfraproject/wlan-cloud-lib-poco.git
				synced 2025-10-31 02:27:56 +00:00 
			
		
		
		
	#3215: XML parser returns item from different element in a array
This commit is contained in:
		| @@ -53,7 +53,7 @@ protected: | ||||
| 	void dispatchNodeRemovedFromDocument(); | ||||
| 	void dispatchNodeInsertedIntoDocument(); | ||||
|  | ||||
| 	static const Node* findNode(XMLString::const_iterator& it, const XMLString::const_iterator& end, const Node* pNode, const NSMap* pNSMap); | ||||
| 	static const Node* findNode(XMLString::const_iterator& it, const XMLString::const_iterator& end, const Node* pNode, const NSMap* pNSMap, bool& indexBound); | ||||
| 	static const Node* findElement(const XMLString& name, const Node* pNode, const NSMap* pNSMap); | ||||
| 	static const Node* findElement(int index, const Node* pNode, const NSMap* pNSMap); | ||||
| 	static const Node* findElement(const XMLString& attr, const XMLString& value, const Node* pNode, const NSMap* pNSMap); | ||||
|   | ||||
| @@ -311,6 +311,7 @@ bool AbstractContainerNode::hasAttributes() const | ||||
|  | ||||
| Node* AbstractContainerNode::getNodeByPath(const XMLString& path) const | ||||
| { | ||||
| 	bool indexBound; | ||||
| 	XMLString::const_iterator it = path.begin(); | ||||
| 	if (it != path.end() && *it == '/') | ||||
| 	{ | ||||
| @@ -327,18 +328,19 @@ Node* AbstractContainerNode::getNodeByPath(const XMLString& path) const | ||||
| 			for (unsigned long i = 0; i < length; i++) | ||||
| 			{ | ||||
| 				XMLString::const_iterator beg = it; | ||||
| 				const Node* pNode = findNode(beg, path.end(), pList->item(i), 0); | ||||
| 				const Node* pNode = findNode(beg, path.end(), pList->item(i), 0, indexBound); | ||||
| 				if (pNode) return const_cast<Node*>(pNode); | ||||
| 			} | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| 	return const_cast<Node*>(findNode(it, path.end(), this, 0)); | ||||
| 	return const_cast<Node*>(findNode(it, path.end(), this, 0, indexBound)); | ||||
| } | ||||
|  | ||||
|  | ||||
| Node* AbstractContainerNode::getNodeByPathNS(const XMLString& path, const NSMap& nsMap) const | ||||
| { | ||||
| 	bool indexBound; | ||||
| 	XMLString::const_iterator it = path.begin(); | ||||
| 	if (it != path.end() && *it == '/') | ||||
| 	{ | ||||
| @@ -368,19 +370,20 @@ Node* AbstractContainerNode::getNodeByPathNS(const XMLString& path, const NSMap& | ||||
| 				for (unsigned long i = 0; i < length; i++) | ||||
| 				{ | ||||
| 					XMLString::const_iterator beg = it; | ||||
| 					const Node* pNode = findNode(beg, path.end(), pList->item(i), &nsMap); | ||||
| 					const Node* pNode = findNode(beg, path.end(), pList->item(i), &nsMap, indexBound); | ||||
| 					if (pNode) return const_cast<Node*>(pNode); | ||||
| 				} | ||||
| 			} | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| 	return const_cast<Node*>(findNode(it, path.end(), this, &nsMap)); | ||||
| 	return const_cast<Node*>(findNode(it, path.end(), this, &nsMap, indexBound)); | ||||
| } | ||||
|  | ||||
|  | ||||
| const Node* AbstractContainerNode::findNode(XMLString::const_iterator& it, const XMLString::const_iterator& end, const Node* pNode, const NSMap* pNSMap) | ||||
| const Node* AbstractContainerNode::findNode(XMLString::const_iterator& it, const XMLString::const_iterator& end, const Node* pNode, const NSMap* pNSMap, bool& indexBound) | ||||
| { | ||||
| 	indexBound = false; | ||||
| 	if (pNode && it != end) | ||||
| 	{ | ||||
| 		if (*it == '[') | ||||
| @@ -406,7 +409,8 @@ const Node* AbstractContainerNode::findNode(XMLString::const_iterator& it, const | ||||
| 						while (it != end && *it != ']') value += *it++; | ||||
| 					} | ||||
| 					if (it != end) ++it; | ||||
| 					return findNode(it, end, findElement(attr, value, pNode, pNSMap), pNSMap); | ||||
| 					bool ib; | ||||
| 					return findNode(it, end, findElement(attr, value, pNode, pNSMap), pNSMap, ib); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| @@ -416,17 +420,19 @@ const Node* AbstractContainerNode::findNode(XMLString::const_iterator& it, const | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				XMLString index; | ||||
| 				while (it != end && *it != ']') index += *it++; | ||||
| 				XMLString xmlIndex; | ||||
| 				while (it != end && *it != ']') xmlIndex += *it++; | ||||
| 				if (it != end) ++it; | ||||
| #ifdef XML_UNICODE_WCHAR_T | ||||
| 				std::string idx; | ||||
| 				Poco::UnicodeConverter::convert(index, idx); | ||||
| 				int i = Poco::NumberParser::parse(idx);	 | ||||
| #else | ||||
| 				std::string index; | ||||
| 				Poco::UnicodeConverter::convert(xmlIndex, index); | ||||
| 				int i = Poco::NumberParser::parse(index); | ||||
| #else | ||||
| 				int i = Poco::NumberParser::parse(xmlIndex); | ||||
| #endif | ||||
| 				return findNode(it, end, findElement(i, pNode, pNSMap), pNSMap); | ||||
| 				indexBound = true; | ||||
| 				bool ib; | ||||
| 				return findNode(it, end, findElement(i, pNode, pNSMap), pNSMap, ib); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| @@ -440,8 +446,9 @@ const Node* AbstractContainerNode::findNode(XMLString::const_iterator& it, const | ||||
| 			const Node* pElem = findElement(key, pNode->firstChild(), pNSMap); | ||||
| 			while (!pFound && pElem) | ||||
| 			{ | ||||
| 				pFound = findNode(it, end, pElem, pNSMap); | ||||
| 				if (!pFound) pElem = findElement(key, pElem->nextSibling(), pNSMap); | ||||
| 				bool ib; | ||||
| 				pFound = findNode(it, end, pElem, pNSMap, ib); | ||||
| 				if (!pFound) pElem = ib ? nullptr : findElement(key, pElem->nextSibling(), pNSMap); | ||||
| 				it = itStart; | ||||
| 			} | ||||
| 			return pFound; | ||||
|   | ||||
| @@ -616,7 +616,7 @@ void ElementTest::testNodeByPath() | ||||
| 			<elemA/> | ||||
| 			<elemA/> | ||||
| 		</elem1> | ||||
| 		<elem2> | ||||
| 		<elem2 index="0"> | ||||
| 			<elemB attr1="value1"/> | ||||
| 			<elemB attr1="value2"/> | ||||
| 			<elemB attr1="value3"/> | ||||
| @@ -626,8 +626,9 @@ void ElementTest::testNodeByPath() | ||||
| 			</elemC> | ||||
| 			<elemC attr1="value2"/> | ||||
| 		</elem2> | ||||
| 		<elem2> | ||||
| 		<elem2 index="1"> | ||||
| 			<elemB attr1="value4"/> | ||||
| 			<elemD attr1="value1"/> | ||||
| 		</elem2> | ||||
| 	</root> | ||||
| 	*/ | ||||
| @@ -646,6 +647,10 @@ void ElementTest::testNodeByPath() | ||||
| 	AutoPtr<Element> pElem25 = pDoc->createElement("elemC"); | ||||
| 	AutoPtr<Element> pElem3  = pDoc->createElement("elem2"); | ||||
| 	AutoPtr<Element> pElem31 = pDoc->createElement("elemB"); | ||||
| 	AutoPtr<Element> pElem32 = pDoc->createElement("elemD"); | ||||
|  | ||||
| 	pElem2->setAttribute("index", "0"); | ||||
| 	pElem3->setAttribute("index", "1"); | ||||
|  | ||||
| 	pElem21->setAttribute("attr1", "value1"); | ||||
| 	pElem22->setAttribute("attr1", "value2"); | ||||
| @@ -655,6 +660,7 @@ void ElementTest::testNodeByPath() | ||||
| 	pElem25->setAttribute("attr1", "value2"); | ||||
|  | ||||
| 	pElem31->setAttribute("attr1", "value4"); | ||||
| 	pElem32->setAttribute("attr1", "value1"); | ||||
|  | ||||
| 	AutoPtr<Element> pElem241 = pDoc->createElement("elemC1"); | ||||
| 	AutoPtr<Element> pElem242 = pDoc->createElement("elemC2"); | ||||
| @@ -671,6 +677,7 @@ void ElementTest::testNodeByPath() | ||||
| 	pElem2->appendChild(pElem25); | ||||
|  | ||||
| 	pElem3->appendChild(pElem31); | ||||
| 	pElem3->appendChild(pElem32); | ||||
|  | ||||
| 	pRoot->appendChild(pElem1); | ||||
| 	pRoot->appendChild(pElem2); | ||||
| @@ -750,11 +757,32 @@ void ElementTest::testNodeByPath() | ||||
| 	pNode = pDoc->getNodeByPath("//[@attr1='value1']"); | ||||
| 	assertTrue (pNode == pElem21); | ||||
|  | ||||
| 	pNode = pDoc->getNodeByPath("//[@attr1='value4']"); | ||||
| 	assertTrue (pNode == pElem31); | ||||
|  | ||||
| 	pNode = pDoc->getNodeByPath("//[@attr1='value2']"); | ||||
| 	assertTrue (pNode == pElem22); | ||||
|  | ||||
| 	pNode = pRoot->getNodeByPath("/elem2/*[@attr1='value2']"); | ||||
| 	assertTrue (pNode == pElem22); | ||||
|  | ||||
| 	pNode = pDoc->getNodeByPath("/root/elem2[0]/elemC"); | ||||
| 	assertTrue (pNode == pElem24); | ||||
|  | ||||
| 	pNode = pDoc->getNodeByPath("/root/elem2[1]/elemC"); | ||||
| 	assertTrue (pNode == 0); | ||||
|  | ||||
| 	pNode = pDoc->getNodeByPath("/root/elem2[0]/elemD"); | ||||
| 	assertTrue (pNode == 0); | ||||
|  | ||||
| 	pNode = pDoc->getNodeByPath("/root/elem2[1]/elemD"); | ||||
| 	assertTrue (pNode == pElem32); | ||||
|  | ||||
| 	pNode = pDoc->getNodeByPath("/root/elem2[@index=0]/elemD"); | ||||
| 	assertTrue (pNode == 0); | ||||
|  | ||||
| 	pNode = pDoc->getNodeByPath("/root/elem2[@index=1]/elemD"); | ||||
| 	assertTrue (pNode == pElem32); | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Günter Obiltschnig
					Günter Obiltschnig