替换 Python 中的 XML 字段
Replace XML field in Python
我正在尝试替换 python 中 xml 文件的某些字段,xml 文件如下所示:
...
<DialogEntry ID="179" IsRoot="false" IsGroup="false" NodeColor="Pink" DelaySimStatus="false" FalseCondtionAction="Block" ConditionPriority="Normal">
<Fields>
<Field Hint="(Wird Ingame nicht verwendet.)" Type="Text">
<Title>Title</Title>
<Value>Reaktion TS34 Antwort 2</Value>
</Field>
<Field Hint="The actor who is talking." Type="Actor">
<Title>Actor</Title>
<Value>2</Value>
</Field>
<Field Hint="The actor who is listening." Type="Actor">
<Title>Conversant</Title>
<Value>1</Value>
</Field>
<Field Hint="The text that is spoken by the actor." Type="Localization">
<Title>Dialogue Text</Title>
<Value>[Speaking]</Value>
<Field Hint="Audiofile to play" Type="Text">
<Title>Audio-File</Title>
<Value />
</Field>
</Fields>
<ReviewerNotes />
<ReviewerStatus>None</ReviewerStatus>
<OutgoingLinks />
<ConditionsString />
<UserScript />
</DialogEntry>
</DialogEntries>
请注意 xml 文件由多个 DialogEntries 组成 并且字段比显示的更多,但我想做的是:对于某个 DialogEntry ID 例如 179 我想用 <Title>Audio-File</Title>...<Value>Audiofile_XYZ.mp3</Value>
等通用文本替换: <Title>Audio-File</Title>...<Value />
我一直在尝试使用正则表达式,像这样:
r1 = re.compile("<DialogEntry ID=\"%d\".*?<Title>Audio-File</Title>\n {16}<Value />" % (id_to change),re.DOTALL)
r2 = re.compile("<DialogEntry ID=\"%d\".*?<Title>Audio-File</Title>\n {16}<Value>%s</Value>" % (id_to change, filename), re.DOTALL)
content = re.sub(r1,r2 ,content)
但我卡住了,因为它没有按预期工作。
我遇到的问题是:
- 使 RE 匹配多行(re.DOTALL seams only to work with precompiled REs for re.sub())
- 指示器ID和要替换的部分相距甚远,中间有很多动态文本,如何识别正确的DialogueEntry并且仍然只替换我想更改的部分而无需处理Audio-File 和 ID
之间的标题
你能帮我解决一下,或者告诉我一个更合适的方法来做这些改变吗?
此致,
BPR
您可能应该为您的转换考虑更合适的媒介:XML -> 文本 -> XML 注定会失败/对于重要问题来说不必要的复杂性。
也许最好使用 ElementTree XML API (consider using lxml if performance is important). Then you can modify the XML representation for your <Value/>
nodes in the tree using the API, and then write to an output file.
解析文件
或者,完全 Python 之外(或 几乎 完全,取决于你如何调用它),你甚至可以只使用 XSLT 来转换它XML 略有不同 XML;毕竟这就是它的设计目的。
我正在尝试替换 python 中 xml 文件的某些字段,xml 文件如下所示:
...
<DialogEntry ID="179" IsRoot="false" IsGroup="false" NodeColor="Pink" DelaySimStatus="false" FalseCondtionAction="Block" ConditionPriority="Normal">
<Fields>
<Field Hint="(Wird Ingame nicht verwendet.)" Type="Text">
<Title>Title</Title>
<Value>Reaktion TS34 Antwort 2</Value>
</Field>
<Field Hint="The actor who is talking." Type="Actor">
<Title>Actor</Title>
<Value>2</Value>
</Field>
<Field Hint="The actor who is listening." Type="Actor">
<Title>Conversant</Title>
<Value>1</Value>
</Field>
<Field Hint="The text that is spoken by the actor." Type="Localization">
<Title>Dialogue Text</Title>
<Value>[Speaking]</Value>
<Field Hint="Audiofile to play" Type="Text">
<Title>Audio-File</Title>
<Value />
</Field>
</Fields>
<ReviewerNotes />
<ReviewerStatus>None</ReviewerStatus>
<OutgoingLinks />
<ConditionsString />
<UserScript />
</DialogEntry>
</DialogEntries>
请注意 xml 文件由多个 DialogEntries 组成 并且字段比显示的更多,但我想做的是:对于某个 DialogEntry ID 例如 179 我想用 <Title>Audio-File</Title>...<Value>Audiofile_XYZ.mp3</Value>
<Title>Audio-File</Title>...<Value />
我一直在尝试使用正则表达式,像这样:
r1 = re.compile("<DialogEntry ID=\"%d\".*?<Title>Audio-File</Title>\n {16}<Value />" % (id_to change),re.DOTALL)
r2 = re.compile("<DialogEntry ID=\"%d\".*?<Title>Audio-File</Title>\n {16}<Value>%s</Value>" % (id_to change, filename), re.DOTALL)
content = re.sub(r1,r2 ,content)
但我卡住了,因为它没有按预期工作。 我遇到的问题是:
- 使 RE 匹配多行(re.DOTALL seams only to work with precompiled REs for re.sub())
- 指示器ID和要替换的部分相距甚远,中间有很多动态文本,如何识别正确的DialogueEntry并且仍然只替换我想更改的部分而无需处理Audio-File 和 ID 之间的标题
你能帮我解决一下,或者告诉我一个更合适的方法来做这些改变吗?
此致, BPR
您可能应该为您的转换考虑更合适的媒介:XML -> 文本 -> XML 注定会失败/对于重要问题来说不必要的复杂性。
也许最好使用 ElementTree XML API (consider using lxml if performance is important). Then you can modify the XML representation for your <Value/>
nodes in the tree using the API, and then write to an output file.
或者,完全 Python 之外(或 几乎 完全,取决于你如何调用它),你甚至可以只使用 XSLT 来转换它XML 略有不同 XML;毕竟这就是它的设计目的。