我是新来的,所以如果我无知,请原谅我。这是我的XML数据的一个示例。
<record ID="ART5843">
<title>This is a sample record</title>
<edition></edition>
<persauthorfull>Lykins, Amy D.</persauthorfull>
<persauthorfull>Cantor, James M.</persauthorfull>
<persauthorfull>Blanchard, Ray</persauthorfull>
<keywords>Generic</keywords>
<keywords>Criminal offences</keywords>
<keywords>Civil offences</keywords>
<keywords>Men</keywords>
<keywords>Psychology</keywords>
<keywords>Research</keywords>
<subjects></subjects>
</record>
我需要<persauthorfull>
重命名为<PA>
,然后输出一行用分号分隔,例如......
<PA>Lykins, Amy D.; Cantor, James M.; Blanchard, Ray</PA>
我使用XSL for-each来提取名称,但我不知道如何格式化它们。
<xsl:for-each select="a:persauthorfull">
<PA>
<xsl:attribute name="type">
<xsl:value-of select="."/>
</xsl:attribute>
</PA>
</xsl:for-each>
从我猜测这是对作者的一次迭代 - 还有另一种方式吗?
答案 0 :(得分:1)
如果你想获得:
<PA>Lykins, Amy D.; Cantor, James M.; Blanchard, Ray</PA>
然后你应该做(在XSLT 1.0中):
<PA>
<xsl:for-each select="persauthorfull">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">
<xsl:text>; </xsl:text>
</xsl:if>
</xsl:for-each>
</PA>
答案 1 :(得分:1)
如果您使用的是XSLT 2.0,那么string-join()
就是您所需要的:
<PA>
<xsl:value-of select="string-join(a:persauthorfull,'; ')"/>
</PA>
编辑:正如迈克尔凯所建议的,有一种更简单的方法:
<xsl:value-of select="persauthorfull" separator="; "/>
使用任一行代码,所有persauthorfull
元素的文本内容将被连接,由&#34;分隔; &#34;
让我也清楚你当前的代码是做什么的。你写道:
从我的猜测来看,这是对作者的单一迭代
这是真的 - 如果通过&#34;单次迭代&#34;你的意思是每个a:persauthorfull
元素的一次迭代。如果有多个作者,这将在输出中创建多个PA
元素。此外,作者的姓名最终还是属性type
:
<PA type="Blanchard, Ray"/>
<强>样式表强>
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="record">
<xsl:copy>
<xsl:apply-templates select="@*|persauthorfull[1]/preceding-sibling::*"/>
<PA>
<xsl:value-of select="string-join(persauthorfull,'; ')"/>
</PA>
<xsl:apply-templates select="persauthorfull[last()]/following-sibling::*"/>
</xsl:copy>
</xsl:template>
</xsl:transform>
XML输入
<record ID="ART5843">
<title>This is a sample record</title>
<edition></edition>
<persauthorfull>Lykins, Amy D.</persauthorfull>
<persauthorfull>Cantor, James M.</persauthorfull>
<persauthorfull>Blanchard, Ray</persauthorfull>
<keywords>Generic</keywords>
<keywords>Criminal offences</keywords>
<keywords>Civil offences</keywords>
<keywords>Men</keywords>
<keywords>Psychology</keywords>
<keywords>Research</keywords>
<subjects></subjects>
</record>
XML输出
<record ID="ART5843">
<title>This is a sample record</title>
<edition/>
<PA>Lykins, Amy D.; Cantor, James M.; Blanchard, Ray</PA>
<keywords>Generic</keywords>
<keywords>Criminal offences</keywords>
<keywords>Civil offences</keywords>
<keywords>Men</keywords>
<keywords>Psychology</keywords>
<keywords>Research</keywords>
<subjects/>
</record>
答案 2 :(得分:0)
以下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="/*">
<PA>
<xsl:apply-templates select="persauthorfull"/>
</PA>
</xsl:template>
<xsl:template match="persauthorfull">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()"><xsl:text>;</xsl:text></xsl:if>
</xsl:template>
</xsl:stylesheet>
输出:
<?xml version="1.0" encoding="UTF-8"?>
<PA>Lykins, Amy D.;Cantor, James M.;Blanchard, Ray</PA>
“可以调整”我的意思是 - 例如可以省略XML名称空间声明,但也许你想保留它。我想您可能希望稍后从输入中添加更多信息,这可以很容易地扩展模板
如果您是XSLT的新手,就像它的工作原理一样简短 - <xsl:template match="/*">
匹配来自root的整个输入XML。然后<xsl:apply-templates select="persauthorfull"/>
仅将模板应用于名为persauthorfull
的节点。由于有一个模板匹配这些节点 - <xsl:template match="persauthorfull">
,因此在那里处理节点。将省略所有其他节点。并且<xsl:if test="position()!=last()"><xsl:text>;</xsl:text></xsl:if>
在;
不是position()
时,会在每个节点值之后添加last()
。