2012-05-25 25 views
0

如何在解析XML文檔時刪除所有標記(如果它們沒有特定的屬性)?例如,我希望所有標記(除了根以外)都具有名稱屬性。我使用XML來建立樹型數據庫,並且使用沒有名稱的標籤根本沒有意義。強制屬性存在於XML中的標記中

當然,我只是可以迭代所有標記(深入)並檢查屬性是否存在,但是對於較大的文件需要一些時間。

我想應該有一些選擇使用XMLParser ...可能使用某種模式?

+1

[XSLT](http://en.wikipedia.org/wiki/XSLT)可能很容易做到這一點。 – Chris

回答

0

隨着XPath和LXML,這應該工作:

from lxml import etree 

xml = etree.XML("<root><a name='1'><b name='1-1'>ABC</b></a><a>Does not exist</a><a name='2'>DEF</a><a><b name='3-1'>GHI</b></a></root>") 

print 'Before:' 
print etree.tostring(xml) 

xp = etree.XPath("/*/*[not(@name)]") # or "//*[not(@name)]" to include the root tag 
all_nodes = xp(xml) 
for x in all_nodes: 
    parent = x.getparent() 
    #if parent is None: continue # if the root tag is included, the parent is None 
    parent.remove(x) 

print 'After:' 
print etree.tostring(xml) 
+0

這就像一個魅力!現在我只是在解析後使用它。 – middleofdreams

+0

很高興幫助!確保你閱讀了更多關於XPath的更復雜的問題。 – jadkik94

0

XSLT非常容易。兩個模板規則,標識規則,副本的一切:

<xsl:template match="*"> 
    <xsl:copy> 
    <xsl:copy-of select="@*"/> 
    <xsl:apply-templates/> 
    </xsl:copy> 
</xsl:template> 

和丟棄的元素另一個規則,你不希望:

<xsl:template match="*[not(@specific-attribute)]"/> 
+0

你可以展示如何使用lxml?我也不明白爲什麼我需要這兩條規則,爲什麼丟棄規則還不夠? – middleofdreams

+0

我不知道XSLT,但[關於lxml的此教程](http://lxml.de/xpathxslt.html#xslt)可能會對您有所幫助。 :) – jadkik94

+0

我對lxml一無所知,但這種解決方案是完全通用的,對實際詞彙表的依賴性很小。需要第一條規則的原因是XSLT中的默認內置模板規則在本用例中沒有做到您想要的。 –