Я хотел бы передать определенный параметр в xml, поэтому вместо того, чтобы быть необработанным xml со всеми значениями при его создании, я бы хотел изменить один с параметром (например, пользовательский ввод).
В идеале я искал что-то вроде <title> ¶m1 </title>
и мог позже передать любой желаемый параметр, но я думаю, что это невозможно.
Поэтому, как нельзя передать параметр (или, по крайней мере, из того, что я искал), я подумал о редактировании XML после его создания.
Я искал в основном с Beautifulsoup, потому что это то, что я хочу использовать (и что я использую). Это всего лишь немного моего проекта. например это и это некоторые из моих исследований).
Так что это функция, которую я пытаюсь сделать: у нас есть xml, мы находим часть, которую хотим отредактировать, и редактируем ее (я знаю, что для доступа к ней, она должна быть целым числом pruebaEdit[anyString]
не правильно,
def editXMLTest():
editTest="""<?xml version="1.0" ?>
<books>
<book>
<title>moon</title>
<author>louis</author>
<price>8.50</price>
</book>
</books>
"""
soup =BeautifulSoup(editTest)
for tag in soup.find_all('title'):
print (tag.string, '\n')
#tag.string='invented title'
editTest[tag]='invented title' #I know it has to be an integer, not a string
print()
print(editTest)
Мой ожидаемый вывод должен быть в xml: <title>invented title</title>
вместо <title>moon</title>
.
Редактировать: добавил это в мое исследование
Вы должны напечатать результаты или soup
не оригинальную строку editTest
for tag in soup.find_all('title'):
print (tag.string, '\n')
tag.string='invented title'
print(soup)
С помощью Python lxml
который может запускать сценарии XSLT 1.0, а также механизм синтаксического анализа в BeautifulSoup
, вы можете передавать параметры для изменения файлов XML по мере необходимости. Просто установите <xsl:param>
в скрипте XSLT и в Python, передавая значение через strparam
:
XSLT (сохранить как файл .xsl, специальный файл .xml)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit_xml_declaration="no"/>
<xsl:strip-space elements="*"/>
<!-- INITIALIZE PARAMETER -->
<xsl:param name="new_title" />
<!-- IDENTITY TRANSFORM -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- REWRITE TITLE TEXT -->
<xsl:template match="title">
<xsl:copy>
<xsl:value-of select="$new_title"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Python (см. Вывод ниже как комментарий)
import lxml.etree as et
txt = '''<books>
<book>
<title>moon</title>
<author>louis</author>
<price>8.50</price>
</book>
</books>'''
# LOAD XSL SCRIPT
xml = et.fromstring(txt)
xsl = et.parse('/path/to/XSLTScript.xsl')
transform = et.XSLT(xsl)
# PASS PARAMETER TO XSLT
n = et.XSLT.strparam('invented title')
result = transform(doc, new_title=n)
print(result)
# <?xml version="1.0"?>
# <books>
# <book>
# <title>invented title</title>
# <author>louis</author>
# <price>8.50</price>
# </book>
# </books>
# SAVE XML TO FILE
with open('Output.xml', 'wb') as f:
f.write(result)
Демонстрация Pyfiddle (обязательно нажмите Run и проверьте вывод)
Использование ссылок на сущности, таких как ¶m;
это самая близкая вещь, доступная в самом XML, но она не очень гибкая, потому что расширения сущностей определяются в файле DTD, а не передаются программно в синтаксический анализатор XML. Некоторые парсеры (я не знаю ситуацию с Python) позволяют вам предоставлять EntityResolver, который может программно разрешать ссылки на сущности, но это не будет моим первым подходом.
Конечно, есть языки шаблонов, которые позволяют создавать XML программно. XSLT - самый очевидный выбор; это, вероятно, делает намного больше, чем вам нужно, но это не обязательно недостаток. Некоторые другие параметры перечислены по адресу https://en.wikipedia.org/wiki/Comparison_of_web_template_engines, включая несколько для среды Python. К сожалению, многие из этих инструментов, по моему опыту, не особенно хорошо документированы или поддерживаются, поэтому внимательно изучите их.
Используйте <xsl>
для передачи параметра в xml
cleanSoup = BeautifulSoup(str(soup).replace('moon', valueToChange))
но это работает намного лучше, к сожалению, я не распечатал его должным образом. Спасибо!!