【发布时间】:2014-03-01 19:35:37
【问题描述】:
我有一个类似的 XML 文件
<node>
<properties>
<property name="titleENG">English title</property>
<property name="titleFRE">French title</property>
<property name="descENG">English description</property>
<property name="descFRE">French description</property>
...
</properties>
</node>
作为输出,我想要一个类似的 CSV 文件
title, English title, French title
desc, English description, French description
...
假设我知道可用的语言,但我不知道可用的属性(title、desc、...)
我可以用下面的 XSLT 得到英文字符串
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="@* | node()">
<xsl:apply-templates select="@* | node()"/>
</xsl:template>
<xsl:template match="property">
<xsl:if test="@name[ends-with(.,'ENG')]">
<xsl:variable name="key" select="substring(@name,1,string-length(@name)-3)" />
<xsl:value-of select="$key"/>, <xsl:value-of select="./text()"/><xsl:text> </xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
但是在'if'里面,我还需要name=concat($key,'FRE')的属性值,我该怎么做呢?
任何帮助表示赞赏。
编辑 我想我可以将我的问题改写为(因为我可以轻松地将我当前的集合转换为这个):假设我有一个类似的 XML
<node>
<properties>
<property name="dummy"></property>
<property name="title" lang="ENG">English title</property>
<property name="title" lang="FRE">French title</property>
<property name="desc" lang="ENG">English description</property>
<property name="desc" lang="FRE">French description</property>
...
</properties>
</node>
在这种情况下,如何创建包含两行的 (CSV) 输出,第一列中的名称和下一列中的英语、法语翻译?
【问题讨论】:
-
1. "假设我知道可用的语言" 这些知识将存在于哪里? 2. 您的样式表显示的是 1.0 版,但您使用的是 2.0 版函数 ends-with()。 3. 如果你的输出是 CSV,你为什么要复制节点?
-
1. 我认为这是一个单独的问题;最坏的情况是我对它们进行硬编码,最好的情况是我尝试使用某种数组变量,但我还没有看过它。 2. 我的在线 xslt 测试工具没有报错;感谢您指出了这一点。 3. 我猜你的意思是我可以省略第一个模板?在某一时刻,我似乎需要它通过 xml 进行递归,但显然这确实不再需要了。感谢您指出这一点。
-
1. 这不是一个单独的问题,因为我们需要知道从哪里获取它们以便想出一个可行的解决方案;如果您说它们可以硬编码到样式表中,那么我们就知道了。我们仍然不知道2.您使用的是 XSLT 1.0 还是 2.0。我的意思是在生产中,而不是用于在线测试。
-
XSLT 2.0 没问题(抱歉没有更明确)
-
如果您可以更改源 XML,您还可以考虑使用标准语言代码 (ISO 639-1) 和
xml:lang属性来指定您的语言。这样,您还可以使用lang()函数来选择节点。并且您可以导入语言代码表(我相信在 IANA.org 中您可能会在 XML、CSV 等中找到它们)