Как я могу изменить пространство имен атрибута в xml с помощью python?

В моем случае у меня есть следующий код:

from lxml import etree as et
from lxml.builder import ElementMaker

WSS_SCHEMA = "http://schemas.xmlsoap.org/ws/2002/12/secext"
ACTOR_SCHEMA = "http://xpto"
VERSION_SCHEMA = "2"

NSMAP = {
    'wss': WSS_SCHEMA,
    'S': ACTOR_SCHEMA,
    'at': VERSION_SCHEMA,
}

WSS = ElementMaker(namespace=WSS_SCHEMA, nsmap=NSMAP)

security = WSS.Security()

security.set("{%s}actor" % ACTOR_SCHEMA, ACTOR_SCHEMA)
security.set("{%s}Version" % VERSION_SCHEMA, VERSION_SCHEMA)

print(et.tostring(security, encoding = "unicode"))

И я получаю это на выходе:

<wss:Безопасность xmlns:wss="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:S="http://xpto" xmlns:at="2" S:actor=" http://xpto" по адресу: Версия = "2"/>

Мой желаемый результат таков:

<wss:Безопасность xmlns:wss="http://schemas.xmlsoap.org/ws/2002/12/secext" S:actor="http://xpto" at:Version="2"/>

Есть ли у кого-нибудь предложения о том, как удалить эти два атрибута или как добавить только нужные атрибуты с соответствующими пространствами имен?

Вам нужно вставить актор и at как обычные атрибуты в узле безопасности, а не как пространства имен. Может быть достаточно удалить их из nsmap.

LMC 11.05.2023 19:41

Да, я понимаю, о чем вы говорите, я уже пробовал это, но когда я удаляю из nsmap, все равно не работает, с вашими предложениями я получил этот вывод: <wss:Security xmlns:wss = "schemas.xmlsoap. org/ws/2002/12/secext " xmlns:ns0 = " xpto " xmlns:ns1 = "2" ns0:actor = " xpto" ns1:Version = "2"/>

arleite 12.05.2023 11:31

Если вам нужны атрибуты с указанием пространства имен, вы должны определить пространство имен где-то в документе перед их использованием. Что-то вроде xmlns:S = "http://xpto" xmlns:at = "example.com"

LMC 12.05.2023 15:08
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
3
83
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пространства имен должны быть определены где-то в документе перед их использованием.

from lxml import etree as et
from lxml.builder import ElementMaker

WSS_SCHEMA = "http://schemas.xmlsoap.org/ws/2002/12/secext"
ACTOR_SCHEMA = "http://xpto"
VERSION_SCHEMA = "example.com"

RNSMAP = {
    'S': ACTOR_SCHEMA,
    'at': VERSION_SCHEMA,
}

NSMAP = {
    'wss': WSS_SCHEMA
}


WSS = ElementMaker(namespace=WSS_SCHEMA, nsmap=NSMAP)

security = WSS.Security()

security.set("{%s}actor" % ACTOR_SCHEMA, ACTOR_SCHEMA)
security.set("{%s}Version" % VERSION_SCHEMA, "2")

wrapper = ElementMaker(namespace=ACTOR_SCHEMA, nsmap=RNSMAP)

root = wrapper.Wrapper(security)

print(et.tostring(root, encoding = "unicode"))

Результат

<S:Wrapper xmlns:S = "http://xpto" xmlns:at = "example.com">
    <wss:Security xmlns:wss = "http://schemas.xmlsoap.org/ws/2002/12/secext" 
        S:actor = "http://xpto" at:Version = "2"/>
</S:Wrapper>

Если требуется один элемент, то все пространства имен должны быть определены там.

WSS_SCHEMA = "http://schemas.xmlsoap.org/ws/2002/12/secext"
ACTOR_SCHEMA = "http://xpto"
VERSION_SCHEMA = "example.com"
NSMAP = {
    'wss': WSS_SCHEMA,
    'S': ACTOR_SCHEMA,
    'at': VERSION_SCHEMA,
}
WSS = ElementMaker(namespace=WSS_SCHEMA, nsmap=NSMAP)

security = WSS.Security()

security.set("{%s}actor" % ACTOR_SCHEMA, ACTOR_SCHEMA)
security.set("{%s}Version" % VERSION_SCHEMA, "2")

print(et.tostring(security, encoding = "unicode"))

Результат (отступ вручную)

<wss:Security 
     xmlns:S = "http://xpto"
     xmlns:at = "example.com" 
     xmlns:wss = "http://schemas.xmlsoap.org/ws/2002/12/secext"
     S:actor = "http://xpto"
     at:Version = "2"/>

Это именно то, что я хотел, но у меня не может быть элемента Wrapper, и когда я его удаляю, у меня все еще возникает та же проблема с невозможностью переименовать пространства имен, есть ли возможность сохранить элемент Security, удалив Wrapper?

arleite 12.05.2023 19:29

@AndréLeite добавил код для одного элемента. Не совсем то, что вы ожидали, поскольку там необходимо определить пространства имен.

LMC 12.05.2023 21:38

Другие вопросы по теме