我想用逗号分隔几个信息条目。但是,每个条目都可以为空,如果第一个出现的条目为空,则不应出现逗号。例如:
如果我们有四个XSLT参数:姓名,电话号码,地址,职业
我们有
然后最后的字符串应该是:
John,111-111-1111,Imaginary street,Baker
如果名称和电话号码参数为空或为空,则最终字符串应为:
虚构的街道,贝克
如果只有电话号码为空或空,则最终字符串应为:
John,Imaginary street,Baker
在像C#这样的语言中,我会编写如下代码:
foreach (EntryObject entry in entryList)
{
if (firstEntry == true && entry.Type != EntryType.Age && entry.Type != EntryType.Sex)
{
finalString += entry.ValueString;
firstEntry = false;
}
else if (firstEntry == false && entry.Type != EntryType.Age && entry.Type != EntryType.Sex)
{
finalString += ", " + entry.ValueString;
}
}
return finalString;
但是,我听说XSLT中的变量是不可变的。我应该如何在XSLT中解决这个问题?
编辑: xml条目看起来像这样:
<AddressBook>
<PersonalInfo>
<Age>33</Age>
<Sex>Male</Sex>
<Name>John</Name>
<PhoneNumber></PhoneNumber>
<Address>Imaginary Street</Address>
<Occupation>Baker</Occupation>
</PersonalInfo>
</AddressBook>
请注意,某些条目可能为空,我只会使用姓名,电话号码,地址和职业。年龄和性别应该被忽略。
答案 0 :(得分:2)
使用仅匹配非empy元素(string-length(.)>0
或简称string(.)
)的XPath条件,然后使用position()
函数检查元素是否是第一个元素。输入XML:
<root>
<item>
<name>John</name>
<phoneNumber>111-111-1111</phoneNumber>
<address>Imaginary street</address>
<occupation>Baker</occupation>
</item>
<item>
<name>Jane</name>
<address>Another street</address>
<occupation>Decorator</occupation>
</item>
<item>
<address>Unknown</address>
</item>
</root>
XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="item">
<textItem>
<xsl:for-each select="*[string(.)]">
<xsl:if test="position()>1">
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:value-of select="."/>
</xsl:for-each>
</textItem>
</xsl:template>
<xsl:template match="text()">
</xsl:template>
<xsl:template match="root">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
</xsl:stylesheet>
其中第一个模板是实际工作的模板,<xsl:template match="text()">
删除不匹配元素中包含的文本(默认情况下,XSLT处理器会将此类文本复制到输出中),<xsl:template match="root">
生成根元素输出文件。
结果:
<root>
<textItem>John,111-111-1111,Imaginary street,Baker</textItem>
<textItem>Jane,Another street,Decorator</textItem>
<textItem>Unknown</textItem>
</root>
如果您只对某些字段感兴趣,可以使用union运算符(|
)选择它们 - 例如如果您只想在上面的示例中使用电话,地址和职业,请将XSLT修改为:
<xsl:template match="item">
<textItem>
<xsl:for-each select="(phoneNumber|address|occupation)[string(.)]">
<xsl:if test="position()>1">
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:value-of select="."/>
</xsl:for-each>
</textItem>
</xsl:template>
<xsl:template match="text()">
</xsl:template>
<xsl:template match="root">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:2)
以下是一个通用解决方案,它接受“黑名单”元素名称列表作为参数:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pIgnoreThese" select="' Age Sex '"/>
<xsl:template match="PersonalInfo">
<xsl:apply-templates select=
"*[normalize-space()
and
not(contains($pIgnoreThese, concat(' ', name(), ' ')))
]"/>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="PersonalInfo/*">
<xsl:if test="position() >1">, </xsl:if>
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<AddressBook>
<PersonalInfo>
<Age>33</Age>
<Sex>Male</Sex>
<Name>John</Name>
<PhoneNumber>111-111-1111</PhoneNumber>
<Address>Imaginary Street</Address>
<Occupation>Baker</Occupation>
</PersonalInfo>
<PersonalInfo>
<Age>33</Age>
<Sex>Male</Sex>
<Name></Name>
<PhoneNumber></PhoneNumber>
<Address>Imaginary Street</Address>
<Occupation>Baker</Occupation>
</PersonalInfo>
<PersonalInfo>
<Age>33</Age>
<Sex>Male</Sex>
<Name>John</Name>
<PhoneNumber></PhoneNumber>
<Address>Imaginary Street</Address>
<Occupation>Baker</Occupation>
</PersonalInfo>
</AddressBook>
产生了想要的正确结果:
John, 111-111-1111, Imaginary Street, Baker
Imaginary Street, Baker
John, Imaginary Street, Baker