XSLT 1.0:如何根据值确定节点的位置

  • 本文关键字:节点 位置 何根 XSLT xslt-1.0
  • 更新时间 :
  • 英文 :


感谢您的宝贵时间!我试图根据节点的值获得节点的位置,这样我就可以得到相应的条目。请让我举个例子给你们看,这样会更容易解释。

这是源XML:

<?xml version="1.0" encoding="UTF-8"?>
<sampleSourceXML>
<Table>
<Header>
<Column>Name</Column>
<Column>Surname</Column>
<Column>Title</Column>
</Header>
<Body>
<Row>
<Entry>James</Entry>
<Entry>Bond</Entry>
<Entry>Mr</Entry>
</Row>
<Row>
<Entry>Harry</Entry>
<Entry>Potter</Entry>
<Entry>Mr</Entry>
</Row>
</Body>
</Table>
</sampleSourceXML>

这是我想要实现的结果XML:

<?xml version="1.0" encoding="UTF-8"?>
<sampleResultXML>
<Person>
<FirstName>James</FirstName>
<LastName>Bond</LastName>
<Title>Mr</Title>
</Person>
<Person>
<FirstName>Harry</FirstName>
<LastName>Potter</LastName>
<Title>Mr</Title>
</Person>
</sampleResultXML>

我用这个XSLT试了试:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
<xsl:element name="sampleResultXML">
<xsl:for-each select="sampleSourceXML/Table/Rows/Row">
<xsl:element name="Person">
<xsl:element name="FirstName">
<xsl:value-of select="./Entry[1]/text()"></xsl:value-of>
</xsl:element>
<xsl:element name="LastName">
<xsl:value-of select="./Entry[2]/text()"></xsl:value-of>
</xsl:element>
<xsl:element name="Title">
<xsl:value-of select="./Entry[3]/text()"></xsl:value-of>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

这工作。

但是!源XML可以有不同的顺序。例如,Title元素可以位于Name元素之上。因此,XSLT中硬编码的位置(例如Entry[3])将不再工作。

头顺序和条目顺序总是对应的。因此,如果列标题在位置3,那么将是相应的行。

我需要一种方法来动态获取Title元素的位置。所以我必须遍历Column元素,直到我到达值为title的元素。这个位置,我想我会保存在一个变量(例如Position_Title),这样我就可以填充值以后像这样:

<xsl:element name="Title">
<xsl:value-of select="./Entry[$Position_Title]/text()"></xsl:value-of>
</xsl:element>

然而,我还没能找到一种方法来做到这一点…

你知道我该怎么做吗?

谢谢!

尼克

编辑:谢谢Michael的帮助!下面是我使用的最后一个XSLT:
<xsl:stylesheet version="1.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="/sampleSourceXML">
<xsl:variable name="cols" select="Table/Header/Column"/>
<sampleResultXML>
<xsl:for-each select="Table/Body/Row">
<Person>
<xsl:for-each select="Entry">
<xsl:variable name="i" select="position()"/>
<xsl:variable name="elementName">
<xsl:choose>
<xsl:when test="$cols[$i]='Name'">
<xsl:value-of select="'FirstName'"/>
</xsl:when>
<xsl:when test="$cols[$i]='Surname'">
<xsl:value-of select="'LastName'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$cols[$i]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="{$elementName}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</Person>
</xsl:for-each>
</sampleResultXML>
</xsl:template>
</xsl:stylesheet>

我需要一种方法来动态获取Title元素的位置。所以我必须遍历Column元素,直到我到达值为title的元素。这个位置,我想我会保存在一个变量(例如Position_Title),这样我就可以填充值以后像这样:

我认为如果你从相反的方向做,事情会简单得多。试一试:

XSLT 1.0

<xsl:stylesheet version="1.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="/sampleSourceXML">
<xsl:variable name="cols" select="Table/Header/Column" />
<sampleResultXML>
<xsl:for-each select="Table/Body/Row">
<Person>
<xsl:for-each select="Entry">
<xsl:variable name="i" select="position()" />
<xsl:element name="{$cols[$i]}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each> 
</Person>
</xsl:for-each> 
</sampleResultXML>
</xsl:template>
</xsl:stylesheet>

最新更新