2009-11-15 3 views
0

У меня есть набор выборки XML вернулся:Regex, чтобы получить значение в пределах тега

<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> 

Я хочу, чтобы извлечь все, что в <name></name>, но не сами теги и иметь, что только для первого экземпляра (или на основе какого-либо другого теста выберите, какой элемент).

Возможно ли это с регулярным выражением?

+7

Возможно ли использовать библиотеку разбора xml для вашего языка? Это определенно возможно с помощью регулярного выражения, но вы можете использовать XML-библиотеку намного проще и эффективнее. – Bartek

+0

Также см. Http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – voyager

ответ

1

Лучшим инструментом для такого рода задач является 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; 

Если вы хотите, имя сайта, который имеет идентификатор 56789, используйте этот XPath: /rsp/site[id='56789']/name вместо этого. Я предлагаю вам прочитать W3Schools XPath tutorial для краткого обзора синтаксиса XPath.

2

Не зная своего языка или среды, вот некоторые выражения perl. Надеюсь, это даст вам правильную идею для вашего приложения.

Ваше регулярное выражение, чтобы захватить текстовое содержимое тега будет выглядеть примерно так:

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

Это будет фиксировать содержание каждого тега. Вам нужно будет зациклиться на матче, чтобы извлечь весь контент. Обратите внимание, что это не учитывает теги с самозавершением. Для этого вам понадобится механизм регулярных выражений с отрицательными lookbehinds. Не зная вашей среды, трудно сказать, будет ли она поддерживаться.

Вы также можете просто раздеться все теги из источника, используя что-то вроде:

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

Также в зависимости от среды, если вы можете использовать библиотеку XML-разбора, это сделает вашу жизнь намного проще. В конце концов, используя подход регулярного выражения, вы теряете все, что действительно предлагает вам XML (структурированные данные, контекстная осведомленность и т. Д.).

+0

Да, я пытаюсь использовать Objective-C. Я не хотел добавлять какие-либо дополнительные библиотеки или файлы, я подумал, что, возможно, будет простой способ для строки xml, которую я получаю – Doz

+1

+1 за отличный совет по использованию синтаксического анализа XML. – TrueWill

3

<disclaimer> Я не использую Objective-C </disclaimer>

Вы должны быть с помощью XML parser, not regexes. XML is not a regular language, hence not easely parseable от a regular expression. Don't do it.

Never use regular expressions or basic string parsing to process XML. В настоящее время на всех языках общего пользования имеется превосходная поддержка XML. XML является обманчиво сложным стандартом, и вряд ли ваш код будет правильным в том смысле, что он будет правильно анализировать все правильно сформированные XML-данные, и даже если это так, вы тратите свое время, потому что (как было сказано) каждый язык в общее использование имеет поддержку XML. Непрофессионально использовать регулярные выражения для анализа XML.

Вы можете использовать Expat, с Objective C bindings.

Apple's options are:

  1. CF xml parser
  2. tree based Cocoa parser (10.4 only)
1

Как говорят другие, вы действительно должны использовать NSXMLParser для такого рода вещи.

ОДНАКО, если вы только нужно извлечь материал в тегах имен, то RegexKitLite может сделать это довольно легко:

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

Тщательное о пространствах имен:

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

эквивалентно XML который нарушит код на основе регулярного выражения. Для XML используйте синтаксический анализатор XML. XPath - ваш друг за такие вещи. Код XPath ниже возвращает последовательность строк с информацией вы хотите:

./rsp/site/name/text() 

Какао имеет NSXML support for XPath.

Смежные вопросы