0
我在想如果任何人都可以想出一個更「pythonic」的解決方案來解決我目前正在解決的問題。以xml節點替換文本的pythonic方式
我有一個源XML文件,我正在編寫一個XSLT生成器。源XML的相關部分看起來是這樣的:
...
<Notes>
<Note>
<Code>ABC123</Code>
<Text>Note text contents</Text>
...
</Note>
<Note>
...
</Note>
...
</Notes>
...
而且我有一些對象anaologous這些:
from lxml.builder import ElementMaker
#This element maker has the target output namespace
TRGT = ElementMaker(namespace="targetnamespace")
XSL = ElementMaker(namespace="'http://www.w3.org/1999/XSL/Transform',
nsmap={'xsl':'http://www.w3.org/1999/XSL/Transform'})
#This is the relevant part of the 'generator output spec'
details = {'xpath': '//Notes/Note', 'node': 'Out', 'text': '{Code} - {Text}'}
目的是從「細節」對象產生XSLT的下面的代碼片段:
<xsl:for-each select="//Notes/Note">
<Out><xsl:value-of select="Code"/> - <xsl:value-of select="Text"/></Out>
</xsl:for-each>
我很難做的部分是用XML節點替換{placeholder}文本。我開始試着這樣做:
import re
text = re.sub('\{([^}]*)\}', '<xsl:value-of select="\\1"/>', details['text'])
XSL('for-each',
TRGT(node, text)
select=details['xpath'])
但這逃脫尖括號字符(即使它工作過,如果我是挑剔它意味着我很好的命名空間ElementMakers被繞過,我不喜歡的):
<xsl:for-each select="//Notes/Note">
<Out><xsl:value-of select="Code"/> - <xsl:value-of select="Text"/></Out>
</xsl:for-each>
目前我有這個,但它不覺得很不錯:
start = 0
note_nodes = []
for match in re.finditer('\{([^}]*)\}', note):
text_up_to = note[start:match.start()]
match_node = self.XSL('value-of', select=note[match.start()+1:match.end()-1])
start = match.end()
note_nodes.append(text_up_to)
note_nodes.append(match_node)
text_after = note[start:]
note_nodes.append(text_after)
XSL('for-each',
TRGT(node, *note_nodes)
select=details['xpath'])
有沒有一種更好的方式(例如,以一個正則表達式分割成一個列表,然後將一個函數的元素whic h是比賽)還是我只是過分挑剔?
謝謝!
Spot on。謝謝! – actionshrimp