为了帮助反向工程 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
