XML - 查找节点,使用一个文本节点打印其祖先

时间:2018-02-06 11:48:22

标签: xml xml-parsing


问题可能听起来不清楚,所以我会用例子。

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<root>
  <item>
    <item>
      <item>
        <item>
          <key>test1</key>
          <Name>Daugther E</Name>
        </item>
        <Name>Son C</Name>
      </item>
      <Name>Child B</Name>
    </item>
    <Name>Item A</Name>
  </item>
</root> 

我可以通过XPath轻松找到daugtherE。我想要一些灵活的方式来打印整个层次结构,如

  

[项目A] - &gt; [儿童B] - &gt; [儿子C] - &gt; [女儿E]

有可能吗?这将为我节省大量繁琐的手动搜索和验证。我目前在Windows上使用xmlstarlet来查询和编辑XML。我可以创建python脚本来解析XML DOM树和打印结果,但也许有更强大或更简单的方法。

1 个答案:

答案 0 :(得分:0)

我用XSLT解决了问题:
Is it possible to navigate to the parent node of a matched node during XSLT processing? - 这篇文章是巨大的帮助

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" omit-xml-declaration="yes"/>
  <xsl:template match="//Name[text()='Daugther E']/">
    <xsl:if test="count(ancestor::item) &gt; 1">
      <xsl:apply-templates select="ancestor::item[1]/ancestor::item[1]" mode="backout"/><xsl:text> -></xsl:text>
    </xsl:if>
    <xsl:text>[</xsl:text><xsl:value-of select="."/><xsl:text>]</xsl:text>
  </xsl:template>
  <xsl:template match="item" mode="backout">
    <xsl:choose>
      <xsl:when test="count(ancestor::item) &gt; 0"><xsl:text> - </xsl:text>
        <xsl:apply-templates select="ancestor::item[1]" mode="backout"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>&#xa;</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:if test="count(ancestor::item) &gt; 0">
      <xsl:text> -></xsl:text>
    </xsl:if>
    <xsl:text>[</xsl:text><xsl:value-of select="Name/."/><xsl:text>]</xsl:text>
  </xsl:template>
  <xsl:template match="text()"/>
</xsl:stylesheet>