Регулярное выражение для получения значения в теге

У меня есть образец возвращенного XML:

<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>, но не сами теги, и получить это только для первого экземпляра (или на основе какого-либо другого теста выбрать, какой элемент).

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


person Doz    schedule 15.11.2009    source источник
comment
Можно ли использовать библиотеку синтаксического анализа xml для вашего языка? Это определенно возможно с регулярным выражением, но вы можете обнаружить, что использование библиотеки XML намного проще и эффективнее.   -  person Bartek    schedule 15.11.2009
comment
Также см. stackoverflow.com/questions/1732348/   -  person Esteban Küber    schedule 17.11.2009


Ответы (5)


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

person 0xced    schedule 23.12.2009

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

Вы должны использовать синтаксический анализатор XML, не регулярные выражения. XML не является обычным языком, , следовательно, нелегко проанализировать с помощью регулярное выражение. Не делайте этого.

Никогда не используйте регулярные выражения или базовый синтаксический анализ строк для обработки XML. Каждый язык, который сейчас широко используется, имеет отличную поддержку XML. XML - это обманчиво сложный стандарт, и маловероятно, что ваш код будет правильным в том смысле, что он будет правильно анализировать весь правильно сформированный ввод XML, и даже если это так, вы тратите свое время, потому что (как только что упоминалось) каждый язык в общее использование имеет поддержку XML. Использовать регулярные выражения для синтаксического анализа XML - непрофессионально.

Вы можете использовать Expat с has Объективные привязки C.

Apple предлагает следующие варианты:

  1. CF xml parser.
  2. древовидный синтаксический анализатор Какао (только 10.4)
person Esteban Küber    schedule 15.11.2009

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

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

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

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

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

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

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

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

Как говорят другие, вам действительно стоит использовать _ 1_ для подобных вещей.

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

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

Будьте осторожны с пространствами имен:

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

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

./rsp/site/name/text()

Какао имеет Поддержка NSXML для XPath.

person Harold L    schedule 15.11.2009