如何在解析XML文檔時刪除所有標記(如果它們沒有特定的屬性)?例如,我希望所有標記(除了根以外)都具有名稱屬性。我使用XML來建立樹型數據庫,並且使用沒有名稱的標籤根本沒有意義。強制屬性存在於XML中的標記中
當然,我只是可以迭代所有標記(深入)並檢查屬性是否存在,但是對於較大的文件需要一些時間。
我想應該有一些選擇使用XMLParser ...可能使用某種模式?
如何在解析XML文檔時刪除所有標記(如果它們沒有特定的屬性)?例如,我希望所有標記(除了根以外)都具有名稱屬性。我使用XML來建立樹型數據庫,並且使用沒有名稱的標籤根本沒有意義。強制屬性存在於XML中的標記中
當然,我只是可以迭代所有標記(深入)並檢查屬性是否存在,但是對於較大的文件需要一些時間。
我想應該有一些選擇使用XMLParser ...可能使用某種模式?
隨着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)
這就像一個魅力!現在我只是在解析後使用它。 – middleofdreams
很高興幫助!確保你閱讀了更多關於XPath的更復雜的問題。 – jadkik94
XSLT非常容易。兩個模板規則,標識規則,副本的一切:
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
和丟棄的元素另一個規則,你不希望:
<xsl:template match="*[not(@specific-attribute)]"/>
你可以展示如何使用lxml?我也不明白爲什麼我需要這兩條規則,爲什麼丟棄規則還不夠? – middleofdreams
我不知道XSLT,但[關於lxml的此教程](http://lxml.de/xpathxslt.html#xslt)可能會對您有所幫助。 :) – jadkik94
我對lxml一無所知,但這種解決方案是完全通用的,對實際詞彙表的依賴性很小。需要第一條規則的原因是XSLT中的默認內置模板規則在本用例中沒有做到您想要的。 –
[XSLT](http://en.wikipedia.org/wiki/XSLT)可能很容易做到這一點。 – Chris