为了帮助反向工程 XML文件,我正在使用如下的 Python SAX处理程序. 有人可以提供相同的XSLT来执行相同的工作吗? 这是一个示例输入文件: beatles beatle name firstJohn/first lastLennon/last /name /b
有人可以提供相同的XSLT来执行相同的工作吗?
这是一个示例输入文件:
<beatles> <beatle> <name> <first>John</first> <last>Lennon</last> </name> </beatle> <beatle> <name> <first>Paul</first> <last>McCartney</last> </name> </beatle> <beatle> <name> <first>George</first> <last>Harrison</last> </name> </beatle> <beatle> <name> <first>Ringo</first> <last>Starr</last> </name> </beatle> </beatles>
因此,我们的想法是获取所有唯一路径(忽略属性)的列表,以获得编写模板等的基本起点.
from xml.sax.handler import ContentHandler from xml.sax import make_parser from xml.sax import SAXParseException class ShowPaths(ContentHandler): def startDocument(self): self.unique_paths=[] self.current_path=[] def startElement(self,name,attrs): self.current_path.append(name) path="/".join(self.current_path) if path not in self.unique_paths: self.unique_paths.append(path) def endElement(self,name): self.current_path.pop(); def endDocument(self): for path in self.unique_paths: print path if __name__=='__main__': handler = ShowPaths() saxparser = make_parser() saxparser.setContentHandler(handler) in_f=open("d:\\beatles.xml","r") saxparser.parse(in_f) in_f.close()
以及在示例上运行程序的结果:
beatles beatles/beatle beatles/beatle/name beatles/beatle/name/first beatles/beatle/name/last
So the idea is to get a list of all
unique paths (ignoring attributes) to
get a basic starting point to writing
templates etc
这很简单:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <xsl:template match="*"> <xsl:apply-templates select="ancestor-or-self::*" mode="path"/> <xsl:text>
</xsl:text> <xsl:apply-templates/> </xsl:template> <xsl:template match="*" mode="path"> <xsl:value-of select="concat('/',name())"/> <xsl:variable name="vnumPrecSiblings" select= "count(preceding-sibling::*[name()=name(current())])"/> <xsl:variable name="vnumFollSiblings" select= "count(following-sibling::*[name()=name(current())])"/> <xsl:if test="$vnumPrecSiblings or $vnumFollSiblings"> <xsl:value-of select= "concat('[', $vnumPrecSiblings +1, ']')"/> </xsl:if> </xsl:template> <xsl:template match="text()"/> </xsl:stylesheet>
当此转换应用于提供的XML文档时:
<beatles> <beatle> <name> <first>John</first> <last>Lennon</last> </name> </beatle> <beatle> <name> <first>Paul</first> <last>McCartney</last> </name> </beatle> <beatle> <name> <first>George</first> <last>Harrison</last> </name> </beatle> <beatle> <name> <first>Ringo</first> <last>Starr</last> </name> </beatle> </beatles>
产生了想要的正确结果:
/beatles /beatles/beatle[1] /beatles/beatle[1]/name /beatles/beatle[1]/name/first /beatles/beatle[1]/name/last /beatles/beatle[2] /beatles/beatle[2]/name /beatles/beatle[2]/name/first /beatles/beatle[2]/name/last /beatles/beatle[3] /beatles/beatle[3]/name /beatles/beatle[3]/name/first /beatles/beatle[3]/name/last /beatles/beatle[4] /beatles/beatle[4]/name /beatles/beatle[4]/name/first /beatles/beatle[4]/name/last