Lendo string no arquivo strings.xml

Bom dia mortais,

Tenho as seguintes tag no .xml

< string name=“gend_female”>Feminino</ string>
< string name=“gend_male”>Masculino</ string>

Para não ter que ler cada string, teria alguma forma de ler o arquivo string.xml, e pegar todas as strings que começam com “gend_”, por exemplo?

Brigadão.

Existem inúmeras APIs para transformar um XML em um objeto.

Nesse tópico tem um exemplo de como usar o pacote org.w3c.dom, padrão do Java:
http://www.mkyong.com/java/how-to-read-xml-file-in-java-dom-parser/

Essa API facilita a leitura de qualquer documento XML [através do DOM, ou seja, em árvore]. A leitura é feita nó a nó (cada elemento entre <> é um nó). No seu caso ficaria algo como:

<strings>
	<string name="gend_female">Feminino</string>
	<string name="gend_male">Masculino</string>
</strings>

try     {
    	File fXmlFile = new File("/dados.xml");
    	DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    	DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
    	Document doc = dBuilder.parse(fXmlFile);

    	System.out.println("Elemento raiz :" + doc.getDocumentElement().getNodeName());
    			
    	NodeList nodes = doc.getElementsByTagName("string");
    			
    	System.out.println("----------------------------");

    	for (int temp = 0; temp < nList.getLength(); temp++) {

    		Node nNode = nList.item(temp);
    				
    		System.out.println("\nElemento atual :" + nNode.getNodeName());
    				
    		if (nNode.getNodeType() == Node.ELEMENT_NODE) {
    			Element eElement = (Element) nNode;
    	        	String name = eElement.getAttribute("name");
    			System.out.println("(Gender)name : " + name);
    		}
    	}
        } catch (Exception e) {
    	e.printStackTrace();
        }

Saída

> Elemento raiz :strings
> ----------------------------

> Elemento atual :string
> (Gender)name : gend_female

> Elemento atual :string
> (Gender)name : gend_male

Se os dados que você quer pegar se referem a uma classe (exemplo, carregar a classe “Pessoa” ou “Configuracao”), existem APIs que transformam o conteúdo do XML em uma instância dessa classe (ou em uma lista). A mais comum é a XStream (passo a passo simplificado http://comunidadecc.blogspot.com.br/2009/07/serializando-e-deserializando-objetos.html)

Algumas frameworks disponibilizam uma API específica para isso. O Vraptor por exemplo tem o pacote serialization.xstream, mas usa o com.thoughtworks.xstream: http://www.vraptor.org/pt/docs/trabalhando-com-a-view/

Ou seja, a solução ideal depende da framework que você usa e da finalidade.

1 curtida

Era exatamente isso que estava procurando.

Agora estou com problema no diretório do arquivo strings.xml.

O diretório do meu arquivo é esse:

Saberia me informar como vai ficar a String do construtor File?

Se o arquivo estiver na mesma pasta da classe basta fazer:

getClass().getResource("strings.xml").getFile();

Se você quiser separar esse tipo de arquivo em outra pasta (normalmente é feito assim) pode colocar dentro de /src/main/resources, sendo que ele deve ser compilado na mesma pasta que /src/main/java. Exemplo:

No teu caso talvez seja /app/java e /app/resources.
Dentro da pasta resources você criaria uma estrutura igual à da classe. Ex. /resources/controller/activity/strings.xml e continuar usando o comando acima.

Se quiser colocar em outro diretório, o comando para pegar ficaria assim:

getClass().getClassLoader().getResource("dados/strings.xml").getFile();

Nesse caso o arquivo estaria em “/resources/dados”.

Ainda estou confuso e já testei de várias formas.

De acordo com o print que coloquei, ficaria dessa forma:

getClass().getClassLoader().getResource(“res/values/strings.xml”).getFile();

Levando em consideração que o strings.xml está em res/values/strings.xml
Mas não funciona.

Como você está compilando? Dentro do pacote final (provavelmente um jar) a pasta values está junto com as pastas raízes das suas classes (aquelas em vermelho na sua imagem)?
Talvez a pasta res/ não esteja sendo compilada (tem que estar no build path).

Parece que para Android há uns métodos específicos de lidar com recursos. Veja só essa postagem: http://stackoverflow.com/questions/4081763/access-resource-files-in-android

If you have a file in res/raw/textfile.txt from your Activity/Widget call:

getResources().openRawResource(...) returns an InputStream

The dots should actually be an integer found in R.raw… corresponding to your filename, possibly R.raw.textfile (it’s usually the name of the file without extension)

new BufferedInputStream(getResources().openRawResource(...)); then read the content of the file as a stream