[ Resolvido ] - Dúvidas para ler / alterar elementos específicos em um arquivo Xml - Java - GUJ
[ Resolvido ] - Dúvidas para ler / alterar elementos específicos em um arquivo Xml
jamesfrj Janeiro 25, 2013, 3:50pm #1
Pessoal estou tendo dificuldades sobre como alterar elementos específicos em um arquivo xml.
O problema é o seguinte: tenho um arquivo com muitos elementos, onde somente me interessa alterar alguns. Antes de mais nada dei uma olhada em http://www.guj.com.br/articles#category_18 aí pensei que o meu caso seria usar o DOM pois ele é melhor para a escrita de documentos para os quais não se tem total domínio da estrutura (esquema).
Vi o exemplo em http://www.guj.com.br/articles/22 mas acho que ele não é bem o meu caso, pois o meu documento xml tem muitos elementos que não me interessam, logo não achei interessante criar uma classe para mapear tudo. Gostaria de colocar o documento em memória, acessar e alterar somente os elementos que preciso. Ou seja, um tipo de filtro.
Estou usando as seguintes classes:
Vocês podem me indicar uma abordagem para esse problema ?
charlesbraw Janeiro 25, 2013, 5:52pm #2
Utilize xpath para achar o Node que você precisa.
Então, você altera ele, rola não?
InputSource is = new InputSource(new ByteArrayInputStream(xml.getBytes()));
Element element = (Element) xPath.evaluate("xpath que você quer", document, XPathConstants.NODE);
Acho que assim você vai conseguir alterar com mais facilidade.
nel Janeiro 25, 2013, 6:13pm #3
Considero o xPath uma abordagem realmente interessante e inteligente. A única coisa é você terá que manter o objeto em memória.
Se você o transformar em um arquivo físico, por exemplo, terá de efetuar a leitura, parser, alteração, parser, escrita e etc…
jamesfrj Janeiro 25, 2013, 6:30pm #4
Fala charlesbraw!
Meu Xml é esse aqui abaixo:
<EMX:Model name="Metas"> <ModelEnvProps> <Locator>Metas.xml</Locator> </ModelEnvProps> <ModelProps> <Name>Metas</Name>	</ModelProps>	<Entity_Groups> <Entity name="Atividade Area"> <EntityProps> <Name>ATIVIDADE AREA</Name> </EntityProps>	<Attribute_Groups> <Attribute name="atar sq atividade area"> <AttributeProps> <Name>ATAR SQ ATIVIDADE AREA</Name>	</AttributeProps> </Attribute> <Attribute name="atar nm atividade area"> <AttributeProps> <Name>ATAR NM ATIVIDADE AREA</Name> </AttributeProps> </Attribute>	</Attribute_Groups>	</Entity>	<Entity name="Meta"> <EntityProps> <Name>META</Name> </EntityProps>	<Attribute_Groups> <Attribute name="meta sq meta"> <AttributeProps> <Name>META SQ META</Name> </AttributeProps> </Attribute> <Attribute name="meta ds resumida"> <AttributeProps> <Name>META DS RESUMIDA</Name> </AttributeProps> </Attribute> <Attribute name="meta tx detalhada"> <AttributeProps>	<Name>META TX DETALHADA</Name> </AttributeProps> </Attribute> <Attribute name="meta in peso"> <AttributeProps> <Name>META IN PESO</Name> </AttributeProps> </Attribute> </Attribute_Groups> </Entity>	</Entity_Groups> </EMX:Model>
Preciso alterar todos os elementos que sejam filhos de , ignorando os outros.
Tentei usar o XPath conforme você sugeriu da forma abaixo mas dá NullPointer
String filepath = "teste.xml";
Element element = (Element) xPath.evaluate("Name", doc, XPathConstants.NODE);
System.out.println(element.getTextContent());  // Nullpointer exception nesta linha
charlesbraw Janeiro 25, 2013, 7:41pm #5
Nesse caso você vai ter que trocar essa linha:
XPathExpression expr = xPath.compile("/EMX:Model/*"); NodeList nos = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
ou seja, você vai precisar de uma lista (set) de nós.
Até tentei fazer um exemplo aqui, mas não conseguir acertar o path para seu caso
Posso tentar mais depois, mas tenta da uma analisada nisso que falei.
E tem a observação do nel, isso tudo está em memória hem. Tem que ainda atualizar o xml depois.
charlesbraw Janeiro 25, 2013, 7:49pm #6
Aqui tém vários exemplos:
http://examples.javacodegeeks.com/core-java/xml/xpath/find-elements-by-absolute-location-with-xpath/
Eu que to saindo com pressa agora, porque vou viajar, senão tentava mais.
jamesfrj Janeiro 26, 2013, 1:27am #7
Obrigado, pela ajuda, charlesbraw!
Vou continuar tentando com o XPath. Se conseguir algum progresso posto aqui.
jamesfrj Fevereiro 15, 2013, 4:14pm #8
Obrigado, charlesbraw! Consegui fazer aqui usando .NODESET conforme você falou. Em seguida fiz as alterações no NodeList e com Transformer gerei um outro xml "parseado". Importante lembrar do separador no XPath, que deve ser "//" (para uma barra só).