微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

xml – XSLT:文档分析:如何在文档中输出唯一路径?

为了帮助反向工程 XML文件,我正在使用如下的 Python SAX处理程序.
有人可以提供相同的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>&#xA;</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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。