【发布时间】:2014-08-08 13:20:52
【问题描述】:
在我的 XSLT 中,我正在预处理大型 XML 文件并且必须操作某些值(因为源系统没有按预期交付它们)。
属性“name”和“nm”都应该包含相同的文本。 但是,在原始 XML 中它们是空的。
我需要使用另一个属性“description”和硬编码的查找列表来生成它们(例如,description="Some value" 意味着 nm 和 name 都应该是 "NameABC")。 因为我的查找列表很长,我真的不想在两个模板中实现它,一个用于属性“nm”,一个用于“name”。 相反,我想在一个地方实现我的查找列表,并始终同时更改这两个属性。
有什么办法吗?
这是我的原始 XML(当然是简化示例):
<?xml version="1.0" encoding="UTF-8"?>
<Sample>
<Header>
<Type>A</Type>
</Header>
<DataSet name="">
<Info description="Some value" nm="" other="123"/>
</DataSet>
<DataSet name="">
<Info description="Another value" nm="" other="456"/>
</DataSet>
</Sample>
期望的输出:
<?xml version="1.0" encoding="UTF-8"?>
<Sample>
<Header>
<Type>A</Type>
</Header>
<DataSet name="NameABC">
<Info description="Some value" other="123" nm="NameABC"/>
</DataSet>
<DataSet name="NameXYZ">
<Info description="Another value" other="456" nm="NameXYZ"/>
</DataSet>
</Sample>
我当前的 XSLT(仅更改属性“nm”):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="Sample">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="DataSet">
<xsl:copy>
<xsl:for-each select="@*">
<xsl:attribute namespace="" name="{name()}"><xsl:value-of select="."/></xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="Info">
<xsl:element name="Info">
<xsl:for-each select="@*">
<xsl:attribute namespace="" name="{name()}"><xsl:value-of select="."/></xsl:attribute>
</xsl:for-each>
<xsl:apply-templates select="@nm"/>
<xsl:copy-of select="node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="Info/@nm">
<xsl:choose>
<xsl:when test="/Sample/Header/Type='A' and .=''">
<xsl:attribute name="nm">
<xsl:choose>
<xsl:when test="../@description = 'Some value'">NameABC</xsl:when>
<xsl:when test="../@description = 'Another value'">NameXYZ</xsl:when>
</xsl:choose>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="*">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
【问题讨论】: