我用以下代码编写了XSLT文件:
<xsl:attribute name="subCode">
<xsl:value-of select="Field[@key='XY']"/>
</xsl:attribute>
假设我的INPUT XML看起来像这样:
[...]
<Field key="XY"/>
[...]
在这种情况下,我的XSLT将生成以下输出:
<SomeElement subCode="">
[...]
</SomeElement>
我的问题是:如何删除空属性subCode=""
?
我知道通过使用像<xsl:if>
这样的条件指令是可能的,但是,这似乎是一个丑陋的解决方案(因为我在我的XSLT中生成了数千个类似的属性)。
必须在同一个XSLT中完成。我无法在其他XSLT文件中添加后处理。
除此之外,输出XML已经定义了XSD Schema。模式表明此属性为可选。也许有一些方法可以将XSD架构应用于输出XML?
提前感谢您的帮助!
答案 0 :(得分:4)
使用强>:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<someElement>
<xsl:apply-templates mode="attr"/>
</someElement>
</xsl:template>
<xsl:template match="Field[@key='XY' and not(.='')]" mode="attr">
<xsl:attribute name="subCode">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
将此转换应用于以下XML文档时:
<t>
<Field key="XY"/>
</t>
生成了想要的,正确的结果(根本没有生成属性):
源XML文档是这样的:
<t>
<Field key="XY">1</Field>
</t>
相同的转换再次产生正确的,想要的结果;
<someElement subCode="1"/>
答案 1 :(得分:1)
您可以定义一个模板以匹配该属性,该属性将为缺失的@key
提供正确的输出,但如果您还添加谓词[.!='']
,则它还应忽略没有值的属性。
<xsl:template match="@key[.!='']">
<xsl:attribute name="subCode"><xsl:value-of select="."/></xsl:attribute>
</xsl:template>
或者在您的示例中,如果您只想使用@key='XY'
匹配项:
<xsl:template match="@key[.='XY']">
<xsl:attribute name="subCode"><xsl:value-of select="."/></xsl:attribute>
</xsl:template>
编辑:以下是我用来测试此内容的更完整示例。
源XML
<Fields>
<Field key="XY">A</Field>
<Field key="XY">B</Field>
<Field key="">C</Field>
<Field>D</Field>
</Fields>
伴随XSL
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xsl">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<output>
<xsl:apply-templates />
</output>
</xsl:template>
<xsl:template match="Field">
<xsl:element name="NewField">
<xsl:apply-templates select="@*"/>
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:template match="@key[.='XY']">
<xsl:attribute name="subCode"><xsl:value-of select="."/></xsl:attribute>
</xsl:template>
</xsl:stylesheet>
结果
<output>
<NewField subCode="XY">A</NewField>
<NewField subCode="XY">B</NewField>
<NewField>C</NewField>
<NewField>D</NewField>
</output>
答案 2 :(得分:0)
您应该将以下模板应用于您的属性:
此模板匹配所有键属性值为'XY'的属性:
<xsl:template match="@key['XY']">
<xsl:attribute name="subCode">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
此模板匹配所有键属性,其中(文本)值大于0:
<xsl:template match="@key[string-length(.)]">
<xsl:attribute name="other">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
最后,这个模板匹配所有空的属性(*):
<xsl:template match="@*[not(string-length(.))]" />
所以,如果您有像
这样的输入<?xml version="1.0"?>
<Root>
<Field key='v'>One</Field>
<Field key='XY'>Two</Field>
<Field key='a'>Three</Field>
<Field key='v'>Four</Field>
<Field key='XY'>Five</Field>
<Field>Six</Field>
<Field>Seven</Field>
<Field key='b'>Eight</Field>
<Field key=''>Nine</Field>
<Field></Field>
<Field key='x'>Eleven</Field>
<Field key=''>Twelve</Field>
<Field lat='x'>Thirteen</Field>
</Root>
您可以生成输出:
<?xml version='1.0' ?>
<Root>
<SomeField other="v">One</SomeField>
<SomeField subCode="XY">Two</SomeField>
<SomeField other="a">Three</SomeField>
<SomeField other="v">Four</SomeField>
<SomeField subCode="XY">Five</SomeField>
<SomeField>Six</SomeField>
<SomeField>Seven</SomeField>
<SomeField other="b">Eight</SomeField>
<SomeField>Nine</SomeField>
<SomeField/>
<SomeField other="x">Eleven</SomeField>
<SomeField>Twelve</SomeField>
<SomeField>xThirteen</SomeField>
</Root>
使用以下xslt:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<Root>
<xsl:apply-templates/>
</Root>
</xsl:template>
<xsl:template match="Field">
<xsl:element name="SomeField">
<xsl:apply-templates select="@*"/>
<xsl:value-of select="text()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@key['XY']">
<xsl:attribute name="subCode">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="@key[string-length(.)]">
<xsl:attribute name="other">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="@key[not(string-length(.))]" />
</xsl:stylesheet>