当以下兄弟包含 2 child 元素时,XSL XPath 帮助
XSL XPath help when following siblings contain 2 child elements
我在想出一个 XPath 语句时遇到问题,该语句将帮助我从 Excel XML.
创建 table 内容
这是我的基本 Excel XML 结构:
<Table>
<Row>
<Cell>
<Data ss:Type="String">Title 1</Data>
</Cell>
</Row>
<Row>
<Cell ss:Index="2">
<Data ss:Type="String">Subtitle1</Data>
</Cell>
<Cell>
<Data ss:Type="String">Filename1</Data>
</Cell>
</Row>
<Row>
<Cell ss:Index="2">
<Data ss:Type="String">Subtitle2</Data>
</Cell>
<Cell>
<Data ss:Type="String">Filename2</Data>
</Cell>
</Row>
<Row>
<Cell ss:Index="2">
<Data ss:Type="String">Subtitle3</Data>
</Cell>
<Cell>
<Data ss:Type="String">Filename3</Data>
</Cell>
</Row>
<Row>
<Cell>
<Data ss:Type="String">Title 2</Data>
</Cell>
</Row>
<Row>
<Cell ss:Index="2">
<Data ss:Type="String">Subtitle1</Data>
</Cell>
<Cell>
<Data ss:Type="String">Filename1</Data>
</Cell>
</Row>
<Row>
<Cell ss:Index="2">
<Data ss:Type="String">Subtitle2</Data>
</Cell>
<Cell>
<Data ss:Type="String">Filename2</Data>
</Cell>
</Row>
<Row>
<Cell ss:Index="2">
<Data ss:Type="String">Subtitle3</Data>
</Cell>
<Cell>
<Data ss:Type="String">Filename3</Data>
</Cell>
</Row>
<Row>
<Cell ss:Index="2">
<Data ss:Type="String">Subtitle4</Data>
</Cell>
<Cell>
<Data ss:Type="String">Filename4</Data>
</Cell>
</Row>
如上所示,我有两个标题,每个标题都有一个 Cell 元素,我需要能够获取以下包含两个 Cell 元素的同级标题。我需要输出如下所示:
<ul class="nav">
<li class="sub">
<a href="javascript:void(0);">Title 1</a>
<ul>
<li>
<a href="javascript:void(0);" data-src="Filename1">Subtitle1</a>
</li>
<li>
<a href="javascript:void(0);" data-src="Filename2">Subtitle2</a>
</li>
<li>
<a href="javascript:void(0);" data-src="Filename3">Subtitle3</a>
</li>
</ul>
</li>
<li class="sub">
<a href="javascript:void(0);">Title 2</a>
<ul>
<li>
<a href="javascript:void(0);" data-src="Filename1">Subtitle1</a>
</li>
<li>
<a href="javascript:void(0);" data-src="Filename2">Subtitle2</a>
</li>
<li>
<a href="javascript:void(0);" data-src="Filename3">Subtitle3</a>
</li>
<li>
<a href="javascript:void(0);" data-src="Filename4">Subtitle4</a>
</li>
</ul>
</li>
</ul>
我会提供一些代码,但恐怕我还没有走得太远。我是 XSLT 的菜鸟。
XSLT 1.0 解决方案
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="Table">
<ul class="nav">
<xsl:apply-templates select="Row[count(Cell)=1]"/>
</ul>
</xsl:template>
<xsl:template match="Row[count(Cell)=1]">
<li class="sub">
<a href="javascript:void(0);"><xsl:value-of select="Cell/Data"/></a>
<ul>
<xsl:variable name="heading" select="."/>
<xsl:apply-templates
select="following-sibling::Row[Cell[2]]
[generate-id(preceding-sibling::Row[count(Cell)=1][1]) =
generate-id($heading)]"/>
</ul>
</li>
</xsl:template>
<xsl:template match="Row[Cell[2]]">
<li>
<a href="javascript:void(0);" data-src="{ Cell[2]/Data }">
<xsl:value-of select="Cell[1]/Data"/>
</a>
</li>
</xsl:template>
</xsl:stylesheet>
这是另一种方式(复制了 Mads Hansen 的回答)使用 xsl:key
:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes" method="xml"/>
<xsl:key name="element" match="Row[Cell[2]]" use="generate-id(preceding::Row[count(Cell) = 1][1])"/>
<xsl:template match="Table">
<ul class="nav">
<xsl:apply-templates select="Row[count(Cell)=1]"/>
</ul>
</xsl:template>
<xsl:template match="Row[count(Cell)=1]">
<li class="sub">
<a href="javascript:void(0);">
<xsl:value-of select="Cell/Data"/>
</a>
<ul>
<xsl:apply-templates select="key('element', generate-id())"/>
</ul>
</li>
</xsl:template>
<xsl:template match="Row[Cell[2]]">
<li>
<a href="javascript:void(0);" data-src="{ Cell[2]/Data }">
<xsl:value-of select="Cell[1]/Data"/>
</a>
</li>
</xsl:template>
</xsl:stylesheet>
我在想出一个 XPath 语句时遇到问题,该语句将帮助我从 Excel XML.
创建 table 内容这是我的基本 Excel XML 结构:
<Table>
<Row>
<Cell>
<Data ss:Type="String">Title 1</Data>
</Cell>
</Row>
<Row>
<Cell ss:Index="2">
<Data ss:Type="String">Subtitle1</Data>
</Cell>
<Cell>
<Data ss:Type="String">Filename1</Data>
</Cell>
</Row>
<Row>
<Cell ss:Index="2">
<Data ss:Type="String">Subtitle2</Data>
</Cell>
<Cell>
<Data ss:Type="String">Filename2</Data>
</Cell>
</Row>
<Row>
<Cell ss:Index="2">
<Data ss:Type="String">Subtitle3</Data>
</Cell>
<Cell>
<Data ss:Type="String">Filename3</Data>
</Cell>
</Row>
<Row>
<Cell>
<Data ss:Type="String">Title 2</Data>
</Cell>
</Row>
<Row>
<Cell ss:Index="2">
<Data ss:Type="String">Subtitle1</Data>
</Cell>
<Cell>
<Data ss:Type="String">Filename1</Data>
</Cell>
</Row>
<Row>
<Cell ss:Index="2">
<Data ss:Type="String">Subtitle2</Data>
</Cell>
<Cell>
<Data ss:Type="String">Filename2</Data>
</Cell>
</Row>
<Row>
<Cell ss:Index="2">
<Data ss:Type="String">Subtitle3</Data>
</Cell>
<Cell>
<Data ss:Type="String">Filename3</Data>
</Cell>
</Row>
<Row>
<Cell ss:Index="2">
<Data ss:Type="String">Subtitle4</Data>
</Cell>
<Cell>
<Data ss:Type="String">Filename4</Data>
</Cell>
</Row>
如上所示,我有两个标题,每个标题都有一个 Cell 元素,我需要能够获取以下包含两个 Cell 元素的同级标题。我需要输出如下所示:
<ul class="nav">
<li class="sub">
<a href="javascript:void(0);">Title 1</a>
<ul>
<li>
<a href="javascript:void(0);" data-src="Filename1">Subtitle1</a>
</li>
<li>
<a href="javascript:void(0);" data-src="Filename2">Subtitle2</a>
</li>
<li>
<a href="javascript:void(0);" data-src="Filename3">Subtitle3</a>
</li>
</ul>
</li>
<li class="sub">
<a href="javascript:void(0);">Title 2</a>
<ul>
<li>
<a href="javascript:void(0);" data-src="Filename1">Subtitle1</a>
</li>
<li>
<a href="javascript:void(0);" data-src="Filename2">Subtitle2</a>
</li>
<li>
<a href="javascript:void(0);" data-src="Filename3">Subtitle3</a>
</li>
<li>
<a href="javascript:void(0);" data-src="Filename4">Subtitle4</a>
</li>
</ul>
</li>
</ul>
我会提供一些代码,但恐怕我还没有走得太远。我是 XSLT 的菜鸟。
XSLT 1.0 解决方案
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="Table">
<ul class="nav">
<xsl:apply-templates select="Row[count(Cell)=1]"/>
</ul>
</xsl:template>
<xsl:template match="Row[count(Cell)=1]">
<li class="sub">
<a href="javascript:void(0);"><xsl:value-of select="Cell/Data"/></a>
<ul>
<xsl:variable name="heading" select="."/>
<xsl:apply-templates
select="following-sibling::Row[Cell[2]]
[generate-id(preceding-sibling::Row[count(Cell)=1][1]) =
generate-id($heading)]"/>
</ul>
</li>
</xsl:template>
<xsl:template match="Row[Cell[2]]">
<li>
<a href="javascript:void(0);" data-src="{ Cell[2]/Data }">
<xsl:value-of select="Cell[1]/Data"/>
</a>
</li>
</xsl:template>
</xsl:stylesheet>
这是另一种方式(复制了 Mads Hansen 的回答)使用 xsl:key
:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes" method="xml"/>
<xsl:key name="element" match="Row[Cell[2]]" use="generate-id(preceding::Row[count(Cell) = 1][1])"/>
<xsl:template match="Table">
<ul class="nav">
<xsl:apply-templates select="Row[count(Cell)=1]"/>
</ul>
</xsl:template>
<xsl:template match="Row[count(Cell)=1]">
<li class="sub">
<a href="javascript:void(0);">
<xsl:value-of select="Cell/Data"/>
</a>
<ul>
<xsl:apply-templates select="key('element', generate-id())"/>
</ul>
</li>
</xsl:template>
<xsl:template match="Row[Cell[2]]">
<li>
<a href="javascript:void(0);" data-src="{ Cell[2]/Data }">
<xsl:value-of select="Cell[1]/Data"/>
</a>
</li>
</xsl:template>
</xsl:stylesheet>