國外怎么做直播網(wǎng)站蘭州seo快速優(yōu)化報價
1、問題背景
我們在使用 LXML 庫解析 MathML 表達(dá)式時,可能會遇到這樣一個問題:在遞歸解析過程中,我們可能會重復(fù)進(jìn)入同一個節(jié)點(diǎn),導(dǎo)致解析結(jié)果不正確。例如,我們希望將以下 MathML 表達(dá)式解析為 Python 表達(dá)式:
<?xml version="1.0"?>
<math xmlns="http://www.w3.org/1998/Math/MathML" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/1998/Math/MathML http://www.w3.org/Math/XMLSchema/mathml2/mathml2.xsd"><mrow><mfrac><mn>3</mn></mn><mn>5</mn></mn></mfrac></mrow>
</math>
如果我們使用以下代碼來解析該表達(dá)式:
def parseMML(mmlinput):from lxml import etreefrom StringIO import *from lxml import objectifyexppy=[]events = ("start", "end")context = etree.iterparse(StringIO(mmlinput),events=events)for action, elem in context:if (action=='start') and (elem.tag=='mrow'):exppy+='('if (action=='end') and (elem.tag=='mrow'):exppy+=')'if (action=='start') and (elem.tag=='mfrac'):mmlaux=etree.tostring(elem[0])exppy+=parseMML(mmlaux)exppy+='/'mmlaux=etree.tostring(elem[1])exppy+=parseMML(mmlaux)if action=='start' and elem.tag=='mn': #this is a numberexppy+=elem.textreturn (exppy)
那么我們得到的解析結(jié)果將是:
['(', '(', '3', ')', '/', '(', '5', ')', '(', '3', ')', '(', '5', ')', ')']
而不是我們期望的:
['(', '(', '3', ')', '/', '(', '5', ')', ')']
這是因?yàn)樵诮馕?mfrac
節(jié)點(diǎn)時,我們遞歸調(diào)用了 parseMML
函數(shù)兩次,分別解析了分子和分母。而在解析分子時,我們又遞歸調(diào)用了 parseMML
函數(shù),導(dǎo)致重復(fù)進(jìn)入了 mrow
節(jié)點(diǎn)。
2、解決方案
為了解決這個問題,我們可以使用一個棧來保存已經(jīng)解析過的節(jié)點(diǎn)。當(dāng)我們開始解析一個新的節(jié)點(diǎn)時,我們可以將該節(jié)點(diǎn)壓入棧中。當(dāng)我們完成解析該節(jié)點(diǎn)時,我們可以將該節(jié)點(diǎn)從棧中彈出。這樣,我們就能夠避免重復(fù)進(jìn)入同一個節(jié)點(diǎn)。
以下代碼演示了如何使用棧來避免重復(fù)進(jìn)入同一個節(jié)點(diǎn):
def parseMML(mmlinput):from lxml import etreefrom StringIO import *from lxml import objectifyexppy=[]events = ("start", "end")context = etree.iterparse(StringIO(mmlinput),events=events)nodestack=[]for action, elem in context:if action=='start' and elem.tag in nodestack:continueif (action=='start') and (elem.tag=='mrow'):nodestack.append(elem.tag)exppy+='('if (action=='end') and (elem.tag=='mrow'):nodestack.pop()exppy+=')'if (action=='start') and (elem.tag=='mfrac'):nodestack.append(elem.tag)mmlaux=etree.tostring(elem[0])exppy+=parseMML(mmlaux)exppy+='/'mmlaux=etree.tostring(elem[1])exppy+=parseMML(mmlaux)if action=='start' and elem.tag=='mn': #this is a numberexppy+=elem.textreturn (exppy)
使用該代碼,我們可以得到正確的解析結(jié)果:
['(', '(', '3', ')', '/', '(', '5', ')', ')']