在XSLT的xsl:for-each循环中获取上级节点值的实现方案
问题描述
输入XML结构如下:
<Book> <ID>160-2</ID> <Author> <Name>Mark Polo</Name> </Author> <Cost> <Shop>BookLover</Shop> <Value>2000</Value> </Cost> <Cost> <Shop>MakingBooks</Shop> <Value>1500</Value> </Cost> <Cost> <Shop>AppleBooks</Shop> <Value>3000</Value> </Cost> </Book>
需要转换为每个Cost对应一条BookCost记录的结构:
<BookCost> <ID>160-2</ID> <AuthorName>Mark Polo</AuthorName> <Value>2000</Value> </BookCost> <BookCost> <ID>160-2</ID> <AuthorName>Mark Polo</AuthorName> <Value>1500</Value> </BookCost> <BookCost> <ID>160-2</ID> <AuthorName>Mark Polo</AuthorName> <Value>3000</Value> </BookCost>
已知Book和Cost都是无界元素(可出现多个),计划用<xsl:for-each select="Cost">循环,但不知道如何在循环中获取当前Cost所属Book的ID和作者名称,现有XSLT示例如下:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template match="/"> <resultDocument> <xsl:for-each select="//document/Book/Cost"> <BookCost> <ID>??</ID> <AuthorName>??</AuthorName> <Value> <xsl:value-of select="Value"/> </Value> </BookCost> </xsl:for-each> </resultDocument> </xsl:template> </xsl:stylesheet>
解决方案
要获取当前Cost所属Book的属性,利用XPath的相对路径即可,同时为了支持多个Book元素,建议先遍历Book再遍历其下的Cost,确保每个Cost都能对应到正确的父级Book信息。修改后的XSLT如下:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template match="/"> <resultDocument> <!-- 先遍历所有Book元素,处理每个Book下的Cost --> <xsl:for-each select="//Book"> <!-- 保存当前Book的ID和作者名,避免重复查找 --> <xsl:variable name="bookId" select="ID"/> <xsl:variable name="authorName" select="Author/Name"/> <!-- 遍历当前Book下的所有Cost --> <xsl:for-each select="Cost"> <BookCost> <ID><xsl:value-of select="$bookId"/></ID> <AuthorName><xsl:value-of select="$authorName"/></AuthorName> <Value><xsl:value-of select="Value"/></Value> </BookCost> </xsl:for-each> </xsl:for-each> </resultDocument> </xsl:template> </xsl:stylesheet>
关键说明
- 相对路径获取父级信息:如果不想用变量,也可以直接在
Cost循环里用../ID(表示当前节点的父节点Book下的ID)、../Author/Name获取作者名,效果和变量一致。 - 支持多Book元素:通过先遍历
Book再遍历其下Cost的结构,确保每个Cost都能关联到自己所属的Book的ID和作者名,不会出现跨Book匹配的问题。 - 性能优化:用变量保存当前
Book的ID和作者名,避免在每个Cost循环中重复查找父节点,提升处理效率。
内容的提问来源于stack exchange,提问作者JustStudy
相关产品推荐
相关产品推荐

