使用 XSLT 将 XML 单个元素转换为 XML 属性并在输出中保留为元素
Converting XML single elements to XML attributes using XSLT and keeping as elements in output
我们当前的系统输出 XML 文件,格式如下:
<ResultSet rowCount="2">
<Row>
<Entry>83708</Entry>
<mark>L24653338N1</mark>
<Processed>NO</Processed>
</Row>
<Row>
<Entry>99999</Entry>
<mark>L24653338N1</mark>
<Processed>YES</Processed>
</Row>
</ResultSet>
我需要变身为:
<ResultSet rowCount="2">
<Row Processed="NO">
<Entry>83708</Entry>
<mark>L24653338N1</mark>
<Processed>NO</Processed>
</Row>
<Row Processed="YES">
<Entry>99999</Entry>
<mark>L24653338N1</mark>
<Processed>YES</Processed>
</Row>
</ResultSet>
有人知道如何使用 .XSL 完成此操作吗?
这是我所做的:
</xsl:template>
<xsl:template name="transform">
<Row>
<xsl:if test="$linecount>0">
<xsl:for-each select="/Msg/Body/Payload[./@Role='S']/Msg/Body/Payload[./@sql]/SqlResult/ResultSet/Row">
<xsl:attribute name="pos"><xsl:value-of select="position()"/></xsl:attribute>
<Entry>
<xsl:value-of select="./Entry"/>
</Entry>
<mark>
<xsl:value-of select="./mark"/>
</mark>
<Proccessed>
<xsl:value-of select="./Proccessed"/>
</Proccessed>
</xsl:for-each>
</xsl:if>
</Row>
</xsl:template>
在诸如此类的任务中,您只对 XML 的一部分进行更改,通常的方法是从 Identity Transform
开始
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
它自己会按原样复制所有节点和属性,因此您只需为要更改的内容编写模板。在您的情况下,您要将新的 Processed
属性添加到 Row
元素上。这意味着您只需要一个与 Row
元素匹配的模板,然后添加此属性,例如
<xsl:template match="Row">
<Row Processed="{Processed}">
<xsl:apply-templates select="@*|node()"/>
</Row>
</xsl:template>
请注意您正在创建的属性中 Attribute Value Templates 的使用。大括号 {}
表示要计算的表达式,而不是字面输出,因此属性的值实际上是 Processed
元素的值。
试试这个 XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="Row">
<Row Processed="{Processed}">
<xsl:apply-templates select="@*|node()"/>
</Row>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
请注意,您还调用了 xsl:attribute 创建属性。例如
<xsl:template match="Row">
<Row>
<xsl:attribute name="Processed">
<xsl:value-of select="Processed" />
</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</Row>
</xsl:template>
但是如您所见,这更加冗长,因此尽可能首选属性值模板。
我们当前的系统输出 XML 文件,格式如下:
<ResultSet rowCount="2">
<Row>
<Entry>83708</Entry>
<mark>L24653338N1</mark>
<Processed>NO</Processed>
</Row>
<Row>
<Entry>99999</Entry>
<mark>L24653338N1</mark>
<Processed>YES</Processed>
</Row>
</ResultSet>
我需要变身为:
<ResultSet rowCount="2">
<Row Processed="NO">
<Entry>83708</Entry>
<mark>L24653338N1</mark>
<Processed>NO</Processed>
</Row>
<Row Processed="YES">
<Entry>99999</Entry>
<mark>L24653338N1</mark>
<Processed>YES</Processed>
</Row>
</ResultSet>
有人知道如何使用 .XSL 完成此操作吗?
这是我所做的:
</xsl:template>
<xsl:template name="transform">
<Row>
<xsl:if test="$linecount>0">
<xsl:for-each select="/Msg/Body/Payload[./@Role='S']/Msg/Body/Payload[./@sql]/SqlResult/ResultSet/Row">
<xsl:attribute name="pos"><xsl:value-of select="position()"/></xsl:attribute>
<Entry>
<xsl:value-of select="./Entry"/>
</Entry>
<mark>
<xsl:value-of select="./mark"/>
</mark>
<Proccessed>
<xsl:value-of select="./Proccessed"/>
</Proccessed>
</xsl:for-each>
</xsl:if>
</Row>
</xsl:template>
在诸如此类的任务中,您只对 XML 的一部分进行更改,通常的方法是从 Identity Transform
开始<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
它自己会按原样复制所有节点和属性,因此您只需为要更改的内容编写模板。在您的情况下,您要将新的 Processed
属性添加到 Row
元素上。这意味着您只需要一个与 Row
元素匹配的模板,然后添加此属性,例如
<xsl:template match="Row">
<Row Processed="{Processed}">
<xsl:apply-templates select="@*|node()"/>
</Row>
</xsl:template>
请注意您正在创建的属性中 Attribute Value Templates 的使用。大括号 {}
表示要计算的表达式,而不是字面输出,因此属性的值实际上是 Processed
元素的值。
试试这个 XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="Row">
<Row Processed="{Processed}">
<xsl:apply-templates select="@*|node()"/>
</Row>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
请注意,您还调用了 xsl:attribute 创建属性。例如
<xsl:template match="Row">
<Row>
<xsl:attribute name="Processed">
<xsl:value-of select="Processed" />
</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</Row>
</xsl:template>
但是如您所见,这更加冗长,因此尽可能首选属性值模板。