使用 XSLT 删除 XML 消息中的空元素字段和默认值
Posted
技术标签:
【中文标题】使用 XSLT 删除 XML 消息中的空元素字段和默认值【英文标题】:Remove Empty Elements field and Default value in XML message using XSLT 【发布时间】:2012-01-02 17:48:15 【问题描述】:要求的详细说明是,在Request消息中有一个名为IgnoreEmptyElementInd的字段,它是布尔类型。如果该字段为 True,则需要忽略请求消息中的空元素字段,并将“-111”等默认值设置为找到的默认值。如果为false,则不需要删除空元素,只有找到默认值才会通知它。
我的输入消息是
<SampleUpdRq>
<RqUID>00000000-0000-0000-0000-000000000000</RqUID>
<UpdMsgRqHdr>
<ContextRqHdr>
<RsSelURL>111</RsSelURL>
<NetworkTrnData>
<TerminalIdent>a</TerminalIdent>
<Name>111</Name>
</NetworkTrnData>
<ClientApp>
<Org>dweer</Org>
<Name>aaaaaaaaaaaaaaaaaaa</Name>
<Version>112</Version>
<Channel>abc</Channel>
</ClientApp>
</ContextRqHdr>
<IgnoreEmptyElementInd>true</IgnoreEmptyElementInd>
</UpdMsgRqHdr>
<SampleKeys>
<SampleId>aaaaaaaaaaaaaaaaaaa</SampleId>
<AltSampleIdentifiers>
<SampleIdent>
<SampleIdentType>-111</SampleIdentType>
<SampleIdentValue>ttttttt</SampleIdentValue>
</SampleIdent>
<SampleIdentType/>
</AltSampleIdentifiers>
<SampleType>
<SampleTypeValue>MMA</SampleTypeValue>
<SampleTypeSrc>bbc</SampleTypeSrc>
<CommercialSampleType></CommercialSampleType>
</SampleType>
<CommercialSampleType>-111</CommercialSampleType>
<COID>aaaaa</COID>
</SampleKeys>
</SampleUpdRq>
如果IgnoreEmptyElementInd的值为true,那么输出shd就像
<SampleUpdRq>
<RqUID>00000000-0000-0000-0000-000000000000</RqUID>
<UpdMsgRqHdr>
<ContextRqHdr>
<RsSelURL>111</RsSelURL>
<NetworkTrnData>
<TerminalIdent>a</TerminalIdent>
<Name>111</Name>
</NetworkTrnData>
<ClientApp>
<Org>dweer</Org>
<Name>aaaaaaaaaaaaaaaaaaa</Name>
<Version>112</Version>
<Channel>abc</Channel>
</ClientApp>
</ContextRqHdr>
<IgnoreEmptyElementInd>true</IgnoreEmptyElementInd>
</UpdMsgRqHdr>
<SampleKeys>
<SampleId>aaaaaaaaaaaaaaaaaaa</SampleId>
<AltSampleIdentifiers>
<SampleIdent>
<SampleIdentType>Default Found</SampleIdentType>
<SampleIdentValue>ttttttt</SampleIdentValue>
</SampleIdent>
</AltSampleIdentifiers>
<SampleType>
<SampleTypeValue>MMA</SampleTypeValue>
<SampleTypeSrc>bbc</SampleTypeSrc>
</SampleType>
<CommercialSampleType>Default Found</CommercialSampleType>
<COID>aaaaa</COID>
</SampleKeys>
</SampleUpdRq>
如果IgnoreEmptyElementInd的值为false,则输出shd如下
<SampleUpdRq>
<RqUID>00000000-0000-0000-0000-000000000000</RqUID>
<UpdMsgRqHdr>
<ContextRqHdr>
<RsSelURL>111</RsSelURL>
<NetworkTrnData>
<TerminalIdent>a</TerminalIdent>
<Name>111</Name>
</NetworkTrnData>
<ClientApp>
<Org>dweer</Org>
<Name>aaaaaaaaaaaaaaaaaaa</Name>
<Version>112</Version>
<Channel>abc</Channel>
</ClientApp>
</ContextRqHdr>
<IgnoreEmptyElementInd>false</IgnoreEmptyElementInd>
</UpdMsgRqHdr>
<SampleKeys>
<SampleId>aaaaaaaaaaaaaaaaaaa</SampleId>
<AltSampleIdentifiers>
<SampleIdent>
<SampleIdentType>Default Found</SampleIdentType>
<SampleIdentValue>ttttttt</SampleIdentValue>
</SampleIdent>
<SampleIdentType/>
</AltSampleIdentifiers>
<SampleType>
<SampleTypeValue>MMA</SampleTypeValue>
<SampleTypeSrc>bbc</SampleTypeSrc>
<CommercialSampleType/>
</SampleType>
<CommercialSampleType>Default Found</CommercialSampleType>
<COID>aaaaa</COID>
</SampleKeys>
</SampleUpdRq>
我写过这样的 XSL:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*[not(node())]" />
<xsl:template match="*[. = '-111']">
<xsl:copy>
<xsl:text>Default Found</xsl:text>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
非常感谢专业人士的帮助,对造成的混乱表示歉意。提前致谢。
【问题讨论】:
您的第一个 XSLT 示例有version="2.0"
,您使用 XSLT 2.0 处理器吗?并考虑发布一个具有代表性的 XML 输入示例以及您要创建的相应结果,然后我们可以建议正确的 XSLT 解决方法。
您需要定义用于删除元素的条件。请编辑问题并添加。
@Vinay:IgnoreEmptyElementInd 是否适用于整个 XML 文档,还是仅适用于 UpdMsgRqHdr 元素?
@Tim C :IgnoreEmptyElementInd 将应用于除 UpdMsgRqHdr 元素之外的整个 XML 文档。 IgnoreEmptyElementInd 将是 UpdMsgRqHdr 的最后一个元素,因此对于 IgnoreEmptyElementInd 之后的元素,应该应用该规则。
@Tim C:这是否可以在 XSL 中完成??
【参考方案1】:
在您的一个 cmets 中,您说“应应用 IgnoreEmptyElementInd 之后的元素,应应用该规则”,在这种情况下,听起来您需要利用 XPath 中的“前一个”轴来确定值。
因此,您可以使用此模板扩展您的 XSLT,以在 IgnoreEmptyElementInd 设置为 true 时忽略空节点。
<xsl:template
match="*[not(node())][preceding::IgnoreEmptyElementInd[. = 'true']]"/>
所以,给定以下 XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*[not(node())][preceding::IgnoreEmptyElementInd[. = 'true']]"/>
<xsl:template match="*[. = '-111']">
<xsl:copy>
<xsl:text>Default Found</xsl:text>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当应用于您的示例 XML 时,将输出以下内容
<SampleUpdRq>
<RqUID>00000000-0000-0000-0000-000000000000</RqUID>
<UpdMsgRqHdr>
<ContextRqHdr>
<RsSelURL>111</RsSelURL>
<NetworkTrnData>
<TerminalIdent>a</TerminalIdent>
<Name>111</Name>
</NetworkTrnData>
<ClientApp>
<Org>dweer</Org>
<Name>aaaaaaaaaaaaaaaaaaa</Name>
<Version>112</Version>
<Channel>abc</Channel>
</ClientApp>
</ContextRqHdr>
<IgnoreEmptyElementInd>true</IgnoreEmptyElementInd>
</UpdMsgRqHdr>
<SampleKeys>
<SampleId>aaaaaaaaaaaaaaaaaaa</SampleId>
<AltSampleIdentifiers>
<SampleIdent>
<SampleIdentType>Default Found</SampleIdentType>
<SampleIdentValue>ttttttt</SampleIdentValue>
</SampleIdent>
</AltSampleIdentifiers>
<SampleType>
<SampleTypeValue>MMA</SampleTypeValue>
<SampleTypeSrc>bbc</SampleTypeSrc>
</SampleType>
<CommercialSampleType>Default Found</CommercialSampleType>
<COID>aaaaa</COID>
</SampleKeys>
</SampleUpdRq>
当 IgnoreEmptyElementInd 设置为 'false' 时,将输出以下内容
<SampleUpdRq>
<RqUID>00000000-0000-0000-0000-000000000000</RqUID>
<UpdMsgRqHdr>
<ContextRqHdr>
<RsSelURL>111</RsSelURL>
<NetworkTrnData>
<TerminalIdent>a</TerminalIdent>
<Name>111</Name>
</NetworkTrnData>
<ClientApp>
<Org>dweer</Org>
<Name>aaaaaaaaaaaaaaaaaaa</Name>
<Version>112</Version>
<Channel>abc</Channel>
</ClientApp>
</ContextRqHdr>
<IgnoreEmptyElementInd>false</IgnoreEmptyElementInd>
</UpdMsgRqHdr>
<SampleKeys>
<SampleId>aaaaaaaaaaaaaaaaaaa</SampleId>
<AltSampleIdentifiers>
<SampleIdent>
<SampleIdentType>Default Found</SampleIdentType>
<SampleIdentValue>ttttttt</SampleIdentValue>
</SampleIdent>
<SampleIdentType/>
</AltSampleIdentifiers>
<SampleType>
<SampleTypeValue>MMA</SampleTypeValue>
<SampleTypeSrc>bbc</SampleTypeSrc>
<CommercialSampleType/>
</SampleType>
<CommercialSampleType>Default Found</CommercialSampleType>
<COID>aaaaa</COID>
</SampleKeys>
</SampleUpdRq>
【讨论】:
感谢@Tim C 的回复。我还有1 个疑问,在上面的XML msg deris 字段中称为IgnoreEmptyElementInd dis 是布尔类型。如果IgnoreEmptyElementInd的值为true =>需要删除消息中的所有空元素字段=>并且会有一些默认值,例如Date类型字段的“1200-1-1”和整数类型字段的“-111” ,对于具有这些值的元素,仅保留元素字段 shd。如果值为false =>不需要删除消息中的空元素字段=>需要像上面提到的那样删除具有默认值的元素。在XSL中可以吗? 你要么需要修改原问题,要求完整详细,所以没有误解。如果你给出“IgnoreEmptyElementInd”如何工作的完整规则,应该可以做到。 用详细要求更改了原始问题。以上是关于使用 XSLT 删除 XML 消息中的空元素字段和默认值的主要内容,如果未能解决你的问题,请参考以下文章