[英]How to traverse through XML document tags using lxml similarly to ElementTree
目前我正在編輯 XML 文檔,我必須在其中編輯一些標簽及其屬性。 到目前為止,我一直在使用ElementTree
庫,但是我遇到了命名空間保存的問題,所以我試圖重寫我的腳本以使用lxml
。 但是,在遍歷文檔標簽的情況下, ElementTree
對我來說非常合乎邏輯。 下面作為示例,我將提供將刪除 XML 中的Ext
標記的代碼,並將Resolution
標記文本更改為不同的值。
元素樹:
namespaces = dict([elem for _, elem in ET.iterparse(adiPath, events=['start-ns'])])
for ns in namespaces:
ET.register_namespace(ns, namespaces[ns])
for asset in root.findall('.//{*}Asset'):
if 'title:TitleType' in asset.attrib.values():
ext = asset.find('.//{*}Ext')
if ext != None:
asset.remove(ext)
if 'content:PreviewType' in asset.attrib.values():
resolution = asset.find(".//{*}Resolution")
resolution.text = 'different value'
是否可以以與上述類似的方式遍歷 XML 文件,而不是ET
使用lxml
?
XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<ADI3 xmlns="urn:cablelabs:md:xsd:core:3.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:content="urn:cablelabs:md:xsd:content:3.0"
xmlns:core="urn:cablelabs:md:xsd:core:3.0"
xmlns:offer="urn:cablelabs:md:xsd:offer:3.0"
xmlns:terms="urn:cablelabs:md:xsd:terms:3.0"
xmlns:title="urn:cablelabs:md:xsd:title:3.0"
xmlns:adb="urn:adb:md:xsd:adb:01"
xmlns:schemaLocation="urn:adb:md:xsd:adb:01 ADB-EXT-C01.xsd urn:cablelabs:md:xsd:core:3.0 MD-SP-CORE-C01.xsd urn:cablelabs:md:xsd:content:3.0 MD-SP-CONTENT-C01.xsd urn:cablelabs:md:xsd:offer:3.0 MD-SP-OFFER-C01.xsd urn:cablelabs:md:xsd:terms:3.0 MD-SP-TERMS-C01.xsd urn:cablelabs:md:xsd:title:3.0 MD-SP-TITLE-C01.xsd"
xmlns:xml="http://www.w3.org/XML/1998/namespace">
<Asset xsi:type="title:TitleType" uriId="ID" providerVersionNum="5"
internalVersionNum="0" creationDateTime="2020-04-22T00:00:00Z"
startDateTime="2020-03-24T09:00:00Z" endDateTime="2022-10-06T23:59:00Z">
<AlternateId identifierSystem="VOD1.1">ID</AlternateId>
<ProviderQAContact>Contact</ProviderQAContact>
<Ext>
<adb:ExtensionType>
<adb:TitleExt>
<adb:SeriesInfo episodeNumber="16">
<adb:series seriesId="106585" seasonCount="2"/>
<adb:season seasonId="106586" number="1" episodeCount="22"/>
</adb:SeriesInfo>
</adb:TitleExt>
</adb:ExtensionType>
</Ext>
<title:LocalizableTitle xml:lang="pol">
<title:TitleLong>BATWOMAN EP. 16 - THROUGH THE LOOKING GLASS</title:TitleLong>
<title:SummaryLong> Very long summary...</title:SummaryLong>
<title:Actor fullName="Ruby Rose" firstName="Ruby" lastName="Rose"/>
<title:Actor fullName="Rachel Skarsten" firstName="Rachel" lastName="Skarsten"/>
<title:Actor fullName="Meagan Tandy" firstName="Meagan" lastName="Tandy"/>
<title:Actor fullName="Camrus Johnson" firstName="Camrus" lastName="Johnson"/>
<title:Director fullName="Sudz Sutherland" firstName="Sudz" lastName="Sutherland"/>
</title:LocalizableTitle>
<title:Rating ratingSystem="PL">12</title:Rating>
<title:DisplayRunTime>00:40</title:DisplayRunTime>
<title:Year>2019</title:Year>
<title:CountryOfOrigin>US</title:CountryOfOrigin>
<title:Genre>Genre</title:Genre>
<title:ShowType>Movie</title:ShowType>
</Asset>
<Asset xsi:type="offer:CategoryType" uriId="ID">
<AlternateId identifierSystem="VOD1.1">ID</AlternateId>
<offer:CategoryPath>Path</offer:CategoryPath>
</Asset>
<Asset xsi:type="content:MovieType" uriId="namemp4">
<AlternateId identifierSystem="VOD1.1">namemp4</AlternateId>
<content:SourceUrl>name.mp4</content:SourceUrl>
<content:Resolution>resolution</content:Resolution>
<content:Duration>PT0H40M40S</content:Duration>
<content:Language>pol</content:Language>
<content:SubtitleLanguage>pol</content:SubtitleLanguage>
<content:SubtitleLanguage>eng</content:SubtitleLanguage>
</Asset>
<Asset uriId="ID" xsi:type="content:MovieType">
<AlternateId identifierSystem="VOD1.1">ID</AlternateId>
<Provider>Prov</Provider>
<content:SourceUrl>sub.srt</content:SourceUrl>
</Asset>
<Asset uriId="ID" xsi:type="content:MovieType">
<AlternateId identifierSystem="VOD1.1">ID</AlternateId>
<Provider>Prov</Provider>
<content:SourceUrl>sub.srt</content:SourceUrl>
</Asset>
<Asset xsi:type="content:PosterType" uriId="ID">
<AlternateId identifierSystem="VOD1.1">ID</AlternateId>
<content:SourceUrl>poster.jpg</content:SourceUrl>
<content:X_Resolution>700</content:X_Resolution>
<content:Y_Resolution>1000</content:Y_Resolution>
<content:Language>pol</content:Language>
</Asset>
<Asset xsi:type="offer:ContentGroupType" uriId="ID">
<AlternateId identifierSystem="VOD1.1">ID</AlternateId>
<offer:TitleRef uriId="ID"/>
<offer:MovieRef uriId="namets"/>
<offer:MovieRef uriId="subs"/>
<offer:MovieRef uriId="subs"/>
</Asset>
<Asset xsi:type="offer:ContentGroupType" uriId="ID">
<AlternateId identifierSystem="VOD1.1">ID</AlternateId>
<offer:TitleRef uriId="ID"/>
<offer:MovieRef uriId="poster"/>
</Asset>
</ADI3>
關於您的輸入文檔的意見:
xmlns="..."
) 定義為urn:cablelabs:md:xsd:core:3.0
。xmlns:core="urn:cablelabs:md:xsd:core:3.0"
)。xmlns:schemaLocation
是錯誤的,應該是xsi:schemaLocation
。urn:cablelabs:md:xsd:terms:3.0
)的命名空間。當您閱讀本文檔並再次編寫時,正如您的代碼示例所做的那樣,所有信息都將保留。
但不能保證 output 文檔是輸入文檔的逐字符副本。 這不是 XML 的工作原理,這是一個不合理的期望。 重要的保證是 output 文檔在語義上等同於輸入文檔。
當您的代碼運行時,它會生成此 output(刪節):
<core:ADI3
xmlns:adb="urn:adb:md:xsd:adb:01"
xmlns:content="urn:cablelabs:md:xsd:content:3.0"
xmlns:core="urn:cablelabs:md:xsd:core:3.0"
xmlns:offer="urn:cablelabs:md:xsd:offer:3.0"
xmlns:title="urn:cablelabs:md:xsd:title:3.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<core:Asset xsi:type="title:TitleType" uriId="ID" providerVersionNum="5" internalVersionNum="0" creationDateTime="2020-04-22T00:00:00Z" startDateTime="2020-03-24T09:00:00Z" endDateTime="2022-10-06T23:59:00Z">
<core:AlternateId identifierSystem="VOD1.1">ID</core:AlternateId>
<!-- ... -->
</core:Asset>
</core:ADI3>
與以前一樣, ADI3
元素仍位於urn:cablelabs:md:xsd:core:3.0
命名空間中。 這是通過默認命名空間還是通過顯式前綴實現的無關緊要。 ElementTree 知道這個命名空間的前綴——“core”——並決定使用它。 這並沒有錯,它仍然是同樣的事情。
output 中缺少命名空間urn:cablelabs:md:xsd:terms:3.0
(“terms”),因為它在輸入中未使用並且保留未使用的聲明毫無意義。
同樣的事情也適用於“schemaLocation”——因為您將其編寫為命名空間聲明( xmlns:schemaLocation
),ElementTree 看到這個“命名空間”未被使用並剝離了它。 正確的應該是具有命名空間 ( xsi:schemaLocation
) 的屬性。 當您更正該錯誤時,該項目將保留在 output 中。
總結一下:你沒有問題。 output文檔也是一樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.