我已经查看了几篇分别做这些事情的帖子,但还没有成功地将它们组合在一起。
我有一个类似于这个结构的输入:
<Response>
<Confirmation>Success</Confirmation>
<SecondResponse>
<InquiryResponse>
<ID>99999</ID>
<Confirmation>Success</Confirmation>
<Exception/>
<!-- The following structure repeats a varying amount of times -->
<DataNode1>
<!-- Child nodes could be null, transform should remove null nodes -->
<Child1>data</Child1>
...
<Childn>dataN</Childn>
</DataNode1>
...
<DataNodeN>
<Child1>data</Child1>
...
<Childn>dataN</Childn>
</DataNodeN>
</InquiryResponse>
</SecondResponse>
</Response>
现在,我需要完成以下事情:
1)复制<InquiryResponse>
(但不是<InquiryResponse>
自身)的所有子节点
2)排除<Confirmation>
和<Exception>
节点
3) 排除 DataNode 中的任何 null 子节点
4)在DataNode中插入一个新的子元素
所以所需的输出如下所示:
<ID>99999</ID>
<DataNode1>
<Child1>data</Child1>
<ChiildInsert>newData</ChildInsert>
<Childn>dataN</Childn>
</DataNode1>
...
<DataNodeN>
<Child1>data</Child1>
<ChildInsert>newData</ChildInsert>
<Childn>dataN</Childn>
</DataNodeN>
我相信我必须通过为每个 DataNode 创建一个模板(我知道所有可能出现的值)和模板来删除我不想要的节点,然后将它们全部应用于忽略 null 的主副本模板节点。这是我目前使用 2.0 的 XSLT 化身 - 虽然我知道它并不完全完整,但据我所知:
<xsl:stylesheet version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- Remove Unwanted Nodes -->
<xsl:template match='Confirmation|Exception'/>
<!-- DataNode Template -->
<template match='DataNode1'>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<ChildInsert>
<xsl:value-of select='newData'/>
</ChildInsert>
</xsl:copy>
</xsl:template>
<!-- Identity Transform -->
<xsl:template match='@*|node()'>
<xsl:if test='. != ""'>
<xsl:copy>
<xsl:apply-templates select='@*|node()'/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
这是我使用 Saxon-PE 9.3.0.5 生成的输出
<Response>
<SecondResponse>
<InquiryResponse>
<ID>99999</ID>
<DataNode1>
<Child1>data</Child1>
<ChiildInsert>newData</ChildInsert>
<Childn>dataN</Childn>
</DataNode1>
....
<DataNodeN>...</DataNodeN>
</InquiryResponse>
</SecondResponse>
</Response>
显然,我仍然得到了父母的所有回应,因为我没有指定处理它们的方法;但是,每当我尝试将模板与 XPath 匹配时,我得到的是数据,而不是 XML。我知道我可以通过另一个只复制 的子节点的转换来传递它<InquiryResponse>
,但我觉得应该有更优雅的方式来代替它。以下是我仍然面临的问题/疑问。
1)由于使用这样的模板:<xsl:template match='Response'/>
将使我的整个响应无效,我尝试切换识别模板以匹配Response/SecondResponse/InquiryResponse/*
但结果只产生文本数据,而不是 XML。
2)当<Exception>
节点填充了一个值时,它会继续被复制而不是像<Confirmation>
节点一样被移除。
3)如果我想更新一个不为空的子节点的值,我会这样做吗?更新一些子节点还有一个额外的要求,所以我还在考虑怎么做,这似乎是正确的方法,但我想验证一下。
<xsl:template match='childNodeA'>
<childNodeA>
<xsl:value-of select='someValue/>
</childNodeA>
</xsl:template>
如果不清楚,我深表歉意,但请随时要求您提供所需的任何进一步详细信息,并提前非常感谢任何可以提供帮助的人。