XPath i pętla for na NODELIST

0

Cześć, mam taki problem, że w plik xml mam zdefiniowany raport, oraz trzy parametry do niego:

<?xml version="1.0" encoding="UTF-8"?>
<tns:raporty xmlns:tns="http://www.example.org/raporty"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.example.org/raporty xsd/reports.xsd ">
	
	<tns:raport displayName="Dane klientów z bazy" name="przykladowyRaport1">
		<tns:sql>Select client_id, client_number, client_first_name,
			client_last_name from Client</tns:sql>
		<tns:param>
			<tns:name>client_id</tns:name>
			<tns:displayName>Identyfikator</tns:displayName>
			<tns:type>long</tns:type>
			<tns:defaultValue></tns:defaultValue>
		</tns:param>
		<tns:param>
			<tns:name>clinet_first_name</tns:name>
			<tns:displayName>Imię</tns:displayName>
			<tns:type>String</tns:type>
			<tns:defaultValue>Jacek</tns:defaultValue>
		</tns:param>
		<tns:param>
			<tns:name>client_number</tns:name>
			<tns:displayName>Numer Klienta</tns:displayName>
			<tns:type>int</tns:type>
			<tns:defaultValue>{$temp}</tns:defaultValue>
		</tns:param>
	</tns:raport>
</tns:raporty>

I teraz mam taki kod:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			factory.setNamespaceAware(true);
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document doc = builder.parse(input);
			XPathFactory xpathFactory = XPathFactory.newInstance();
			XPath xpath = xpathFactory.newXPath();

			NamespaceContext ctx = new NamespaceContext() {
				public String getNamespaceURI(String prefix) {
					String uri;
					if (prefix.equals("tns"))
						uri = "http://www.example.org/raporty";
					else if (prefix.equals("cns"))
						uri = "http://www.example.org/constant";
					else
						uri = null;
					return uri;
				}

				// Dummy implementation - not used!
				public Iterator getPrefixes(String val) {
					return null;
				}

				// Dummy implemenation - not used!
				public String getPrefix(String uri) {
					return null;
				}
			};
			xpath.setNamespaceContext(ctx);
//			XPathExpression expr = xpath.compile("//tns:raport");
			Node raport = (Node) xpath.evaluate("//tns:raport", doc, XPathConstants.NODE);
			Node reportNameNode = raport.getAttributes().getNamedItem("name");
			Node reportDisplayNameNode = raport.getAttributes().getNamedItem("displayName");
			Node sqlNode = (Node) xpath.evaluate("//tns:sql", raport, XPathConstants.NODE);
			NodeList params = (NodeList) xpath.evaluate("//tns:param", raport, XPathConstants.NODESET);
			Report report = new Report();
			report.setName(reportNameNode.getTextContent());
			report.setDisplayName(reportDisplayNameNode.getTextContent());
			report.setSql(sqlNode.getTextContent());
			Map<String, ReportParam> hashParams = new HashMap<String, ReportParam>();
			Element param = null;
			for (int i = 0; i < params.getLength(); i++) {
				param = (Element) params.item(i);
				String paramName = xpath.evaluate("//tns:name", param);
				String paramDisplayName = xpath.evaluate("//tns:displayName", param);
				String type = xpath.evaluate("//tns:type", param);
				String defaultValue = xpath.evaluate("//tns:defaultValue", param);
				hashParams.put(paramName, createParam(paramName, paramDisplayName, type, defaultValue));
			}
			// test:
			Iterator<Entry<String, ReportParam>> it = hashParams.entrySet().iterator();
			while (it.hasNext()) {
				ReportParam param2 = it.next().getValue();
				System.out.println(param2.getName());
				System.out.println(param2.getDefaultValue());
				System.out.println(param2.getType());
			}
			//test
			report.setParams(hashParams);
			return report;

Dlaczego test wypisuje mi cały czas tylko zawartość jednego parametru, innymi słowy, wygląda na to że pętla for wykonuje się trzy razy, ale zamiast pobierać w tymi miejscu:

//for...
param = (Element) params.item(i);
				String paramName = xpath.evaluate("//tns:name", param);
				String paramDisplayName = xpath.evaluate("//tns:displayName", param);
				String type = xpath.evaluate("//tns:type", param);
				String defaultValue = xpath.evaluate("//tns:defaultValue", param);

Kolejny param, zachowuje się tak, jakby brałą tylko ten z pozycji 0.
Czy ktoś już miał taki problem?
Będę wdzięczny za pomoc.

0

Hejka.
Jeśli ktoś będzie miał z tym problem kiedyś, to oto rozwiązanie:

//for...
param = (Element) params.item(i);
                                String paramName = xpath.evaluate(".//tns:name", param);
                                String paramDisplayName = xpath.evaluate(".//tns:displayName", param);
                                String type = xpath.evaluate(".//tns:type", param);
                                String defaultValue = xpath.evaluate(".//tns:defaultValue", param);

Trzeba było zmienić *tns:defaultValue na .*tns:defaultValue

Pozdrawiam.

1 użytkowników online, w tym zalogowanych: 0, gości: 1