Pergunta

Eu tenho um conjunto de amostras de XML devolvido:

<rsp stat="ok">
  <site>
    <id>1234</id>
    <name>testAddress</name>
    <hostname>anotherName</hostname>
    ...

  </site>
  <site>
    <id>56789</id>
    <name>ba</name>
    <hostname>alphatest</hostname>
    ...
  </site>
</rsp>

Eu quero extrair tudo dentro <name></name> mas não as próprias tags, e ter isso apenas para a primeira instância (ou com base em algum outro teste, selecione qual item).

Isso é possível com Regex?

Foi útil?

Solução

A melhor ferramenta para esse tipo de tarefa é Xpath.

NSURL *rspURL = [NSURL fileURLWithPath:[@"~/rsp.xml" stringByExpandingTildeInPath]];
NSXMLDocument *document = [[[NSXMLDocument alloc] initWithContentsOfURL:rspURL options:NSXMLNodeOptionsNone error:NULL] autorelease];

NSArray *nodes = [document nodesForXPath:@"/rsp/site[1]/name" error:NULL];
NSString *name = [nodes count] > 0 ? [[nodes objectAtIndex:0] stringValue] : nil;

Se você deseja o nome do site com ID 56789, use este xpath: /rsp/site[id='56789']/name em vez de. Eu sugiro que você leia W3Schools XPath Tutorial Para uma rápida visão geral da sintaxe XPath.

Outras dicas

<disclaimer>Eu não uso o Objective-C</disclaimer>

Você deveria estar usando um Analisador XML, não regexes. XML não é um idioma regular, Portanto, não facilmente parsegurável por uma expressão regular. Não faça isso.

Nunca use expressões regulares ou análise básica de string para processar XML. Todo idioma em uso comum agora tem suporte XML perfeitamente bom. XML é um padrão enganosamente complexo e é improvável que seu código esteja correto no sentido de analisar adequadamente toda a entrada XML bem formada, e até mesmo, se for, você está desperdiçando seu tempo porque (como apenas mencionado) todos os idiomas em O uso comum tem suporte ao XML. Não é profissional usar expressões regulares para analisar XML.

Você poderia usar Expat, com tem Objetivo C ligações.

As opções da Apple são:

  1. o Cf xml analisador
  2. o Analisador de cacau à base de árvores (somente 10.4)

Sem conhecer seu idioma ou ambiente, aqui estão algumas expressões perl. Espero que isso lhe dê a ideia certa para o seu aplicativo.

Sua expressão regular para capturar o conteúdo de texto de uma tag seria algo assim:

m/>([^<]*)</

Isso capturará o conteúdo em cada tag. Você precisará fazer loop na partida para extrair todo o conteúdo. Observe que isso não é responsável por tags auto-terminadas. Você precisaria de um mecanismo regex com aparência negativa para conseguir isso. Sem conhecer seu ambiente, é difícil dizer se ele seria apoiado.

Você também pode simplesmente tirar todas as tags da sua fonte usando algo como:

s/<[^>]*>//g

Também dependendo do seu ambiente, se você puder usar uma biblioteca XML, isso tornará sua vida muito mais fácil. Afinal, ao adotar a abordagem Regex, você perde tudo o que o XML realmente oferece (dados estruturados, conscientização do contexto etc.).

Como outros dizem, você realmente deveria estar usando NSXMLParser Para esse tipo de coisa.

No entanto, se você precisa extrair as coisas nas tags de nome, então Regexkitlite pode fazer isso com bastante facilidade:

NSString * xmlString = ...;
NSArray * captures = [xmlString arrayOfCaptureComponentsMatchedByRegex:@"<name>(.*?)</name>"];
for (NSArray * captureGroup in captures) {
  NSLog(@"Name: %@", [captureGroup objectAtIndex:1];
}

Cuidado com os namespaces:

<prefix:name xmlns:prefix="">testAddress</prefix:name>

é o XML equivalente que quebrará o código baseado em regexp. Para XML, use um analisador XML. XPath é seu amigo por coisas assim. O código XPath abaixo retornará uma sequência de strings com as informações que você deseja:

./rsp/site/name/text()

O cacau tem Suporte NSXML para XPath.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top