Как бороться с "<?" аннотация в XML-файле с Python
Кто-то знает, как бороться с такого рода аннотацией XML с Python
это мой первый раз, когда я увидел это
link id = "752760" resource-uuid = "UUID-9f0575a3-1847-1cde-fd35-f18014fdecf3" resource-id = "570935" resource-type = "fork" type = "ResourceLink"?>
Мне нужно запросить этот вид "элемента", чтобы получить resource-uuid
значение.
Благодарю за любую помощь.
4 ответа
Спасибо всем, я узнал об инструкции по обработке и с этим я провел исследование о том, как с ней обращаться, ниже я позволил себе поцарапаться, если кому-то это понадобится:
from lxml import etree
...
file = 'path/to/file.xml'
tree = etree.parse(file)
result = tree.xpath('//processing-instruction("link")')
for pi in result:
# Each pi is a processing instruction tagged as 'link'
if pi.get('type').__str__() == 'ResourceImport':
# PI with type = ResourceImport
print pi.text # Check the text of tis PI
С помощью lxml
Библиотека легко получить инструкции обработки с помощью XPath.
Я надеюсь, что этот фрагмент кода поможет людям, которые попали сюда из-за этого вопроса.
Вы должны различать инструкцию обработки и объявление xml
Оба написаны одинаково: <?SomeName SomeContent ?>
,
Хотя xml-объявление должно быть на первом месте и начинается с <?xml
другие инструкции по обработке могут появиться (почти) в любом месте XML.
Инструкция обработки должна иметь имя, в то время как содержание не ограничено формально, как содержимое элемента. Это свободный текст...
Так что это правильно сформированный XML:
<root>
<a>test</a>
<?piName some test?>
</root>
Я не работаю с Python, но это вернет ваш PI в SQL-Server:
DECLARE @xml XML=
N'<root>
<a>test</a>
<?link id="752760" resource-uuid="UUID-9f0575a3-1847-1cde-fd35-f18014fdecf3" resource-id="570935" resource-type="fork" type="ResourceLink"?>
</root>';
SELECT @xml.query('/root/processing-instruction("link")');
Даже если ваш контент выглядит как атрибуты: в PI контент - это свободный текст. Таким образом, вы должны разобрать вашу информацию из содержания...
Этот ответ может помочь вам.
Ссылка, на которую вы ссылаетесь, называется инструкцией обработки.
В инструкциях по обработке очень часто используется keyword="value"
синтаксис похож на атрибуты элемента XML, но, к сожалению, это всего лишь соглашение, а не что-то присущее XML, поэтому вам придется самостоятельно анализировать содержимое для извлечения атрибутов. (Саксонский имеет функцию saxon:get-pseudo-attribute()
за это).
Если вы находитесь в Python, возможно, проще выполнить этот дополнительный этап синтаксического анализа в коде Python, а не в коде XPath - если только вам на самом деле не нужно значение как часть более крупного выражения XPath, и в этом случае детализация зависит от того, используете ли вы XPath или XQuery и какая версия.
Если ваш процессор поддерживает XQuery 3.1, вот один из способов решения проблемы:
declare function local:values($pi) {
map:merge(
for $pair in tokenize($pi)
let $key := substring-before($pair, '=')
let $value := replace(substring-after($pair, '='), '^"|"$', '')
return map:entry($key, $value)
)
};
let $xml := document {
<xml>
<?link id="752760" resource-uuid="UUID-9f0575a3-1847-1cde-fd35-f18014fdecf3"
resource-id="570935" resource-type="fork" type="ResourceLink"?>
</xml>
}
for $pi in $xml//processing-instruction('link')
let $values := local:values($pi)
return $values?resource-uuid
Еще одно решение для старых версий XQuery:
let $xml := document {
<xml>
<?link id="752760" resource-uuid="UUID-9f0575a3-1847-1cde-fd35-f18014fdecf3"
resource-id="570935" resource-type="fork" type="ResourceLink"?>
</xml>
}
for $pi in $xml//processing-instruction('link')
for $pair in tokenize($pi, '\s+')[substring-before(., '=') = 'resource-uuid']
return replace(substring-after($pair, '='), '^"|"$', '')
Оба фрагмента кода работают в предположении, что все значения в ваших инструкциях по обработке составлены, как в вашем примере (ключи и значения, разделенные знаком равенства, значения, заключенные в двойные кавычки).