我正在处理一个需要复制和更新以传递进行进一步处理的xml。我遇到的问题是我没有想出一个有效的方法来做到这一点。实质上,我想有条件地更新一些数据,然后复制所有未更新的节点。为什么这是具有挑战性的,是由于要复制的节点的数量和名称的数量和方差。我也不想复制没有文本值的节点。下面是一个例子:使用XSLT有选择地复制和更新xml节点
INPUT XML
<root>
<PersonProfile xmlns:'namespace'>
<ID>0001</ID>
<Name>
<FirstName>Jonathan</FirstName>
<PreferredName>John</PreferredName>
<MiddleName>A</MiddleName>
<LastName>Doe</LastName>
</Name>
<Country>US</Country>
<Biirthdate>01-01-1980</Birthdate>
<BirthPlace>
<City>Townsville</City>
<State>OR</State>
<Country>US</Country>
</Birthplace>
<Gender>Male</Gender>
<HomeState>OR</HomeState>
...
<nodeN>text</nodeN>
</PersonProfile>
</root>
的“PersonProfile”节点仅仅是“根”元素内的几个节点集,每个都有自己的数据的子集的一个。比如邮寄地址,紧急联系信息等等。我试图做的是更新节点,如果变量有一个新的值,那么复制所有未更新的节点。
这里是我当前的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">
<xsl:variable name='updateData' select='document("report")'/>
<!-- Identity Transform -->
<xsl:template match='@* | node()'>
<xsl:if test'. != ""'>
<xsl:copy>
<xsl:apply-templates select='@* | node()'/>
</xsl:copy>
</xsl:if>
</xsl:template>
<!-- Template to update Person Profile -->
<xsl:template match='PersonProfile'>
<xsl:copy>
<xsl:apply-templates select='*'/>
<xsl:element name='Name'>
<xsl:if test='exists($updateData/Preferred)'>
<xsl:element name='FirstName'>
<xsl:value-of select='$reportData/FirstName'/>
</xsl:element>
</xsl:if>
<xsl:if test='exists($updateData/Preferred)'>
<xsl:element name='PreferredName'>
<xsl:value-of select='$updateData/Preferred'/>
</xsl:element>
</xsl:if>
<xsl:if test='exists($updateData/Middle)'>
<xsl:element name='MiddleName'>
<xsl:value-of select='$updateData/Middle'/>
</xsl:element>
</xsl:if>
<xsl:if test='exists($updateData/LastName)'>
<xsl:element name='LastName'>
<xsl:value-of select='$updateData/wd:LastName'/>
</xsl:element>
</xsl:if>
</xsl:element>
<xsl:if test='exists($updateData/Country)'>
<xsl:element name='Country'>
<xsl:value-of select='$updateData/Country'/>
</xsl:element>
</xsl:if>
....
<!-- follows same structure until end of template -->
</xsl:copy>
</xsl:template>
<!-- More Templates to Update other Node sets -->
</xsl:stylesheet>
发生了什么事,现在,是它的复制所有的节点,然后添加更新的值。使用撒克逊PE 9.3.0.5,我会得到类似这样的输出:
样本输出
<root>
<PersonProfile xmlns:'namespace'>
<ID>0001</ID>
<Name>
<FirstName>Jonathan</FirstName>
<PreferredName>John</PreferredName>
<MiddleName>A</MiddleName>
<LastName>Doe</LastName>
</Name>
<Country>US</Country>
<Biirthdate>01-01-1980</Birthdate>
<BirthPlace>
<City>Townsville</City>
<State>OR</State>
<Country>US</Country>
</Birthplace>
<Gender>Male</Gender>
<HomeState>OR</HomeState>
...
<nodeN>text</nodeN>
<PreferredName>Jonathan</PreferredName>
<HomeState>WA</HomeState>
</PersonProfile>
</root>
我意识到这种情况正在发生,因为我在PersonProfile应用模板到所有节点并且我可以指定排除哪些节点,但是我觉得这是一个非常糟糕的解决方案,因为节点的体积可能超过30个或更多,并且需要每个节点的书面值。我相信XML比明确列出每个节点更优雅。我想有一个出这样的:
所需的输出
<root>
<PersonProfile xmlns:'namespace'>
<ID>0001</ID>
<Name>
<FirstName>Jonathan</FirstName>
<PreferredName>Jonathan</PreferredName>
<MiddleName>A</MiddleName>
<LastName>Doe</LastName>
</Name>
<Country>US</Country>
<Biirthdate>01-01-1980</Birthdate>
<BirthPlace>
<City>Townsville</City>
<State>OR</State>
<Country>US</Country>
</Birthplace>
<Gender>Male</Gender>
<HomeState>WA</HomeState>
...
<nodeN>text</nodeN>
</PersonProfile>
</root>
如果有人可以帮助我建立一个模板结构,将在XML结构的工作,我将不胜感激。它需要是“可重用的”,因为有类似的节点结构,比如我需要应用它的Person Profile,但节点名称和元素数量不同,等等。
- Ĵ
所以我找到了一个潜在的解决方案,基本上我为每个xpath创建了一个模板,可以更新然后应用它们 - 哪个工作得很好。我只有1个问题 - 当路径不存在时如何使用模板!可以说这个人缺少主页状态 - 我无法匹配做,所以我怎么能告诉模板来建立新的节点? 谢谢! – 2013-02-26 03:10:04