我正在尝试通过将 XML 文档中的某些文本节点与外部文件中的元素属性匹配来替换/修改它们。
那是我的 XML 文件:
<root>
<level_1>
<item_1>xxxxx</item_1>
<item_2>yyyyy</item_2>
<item_3>zzzzz</item_3>
</level_1>
</root>
XSLT 代码:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:functx="http://www.functx.com">
<xsl:param name="additionalInfoPath"/>
<xsl:output indent="yes" />
<xsl:function name="functx:contains-any-of" as="xs:boolean"
xmlns:functx="http://www.functx.com" >
<xsl:param name="arg" as="xs:string?"/>
<xsl:param name="searchStrings" as="xs:string*"/>
<xsl:sequence select="
some $searchString in $searchStrings
satisfies contains($arg,$searchString)
"/>
</xsl:function>
<xsl:variable name="additionalInfo" select="doc($additionalInfoPath)"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[functx:contains-any-of(string-join(ancestor-or-self::*/upper-case(local-name()),'/'),$additionalInfo//AdditionalInfoData[@Type='ExtraInfo']/InfoDataValue/@TargetElement)]/text()">
<xsl:value-of select="$additionalInfo//AdditionalInfoData[@Type='ExtraInfo']/InfoDataValue[contains(string-join(current()/ancestor-or-self::*/upper-case(local-name()),'/'),@TargetElement)]/text()"/>
</xsl:template>
</xsl:stylesheet>
以及为替换提供值的外部 XML 文档:
<AdditionalInfoRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<AdditionalInfoData Type="ExtraInfo">
<InfoDataValue Name="ITEM_1" TargetElement="ITEM_1" TargetElementValue="">111111</InfoDataValue>
<InfoDataValue Name="LEVEL_1$ITEM_3" TargetElement="LEVEL_1/ITEM_3" TargetElementValue="">333333</InfoDataValue>
</AdditionalInfoData>
</AdditionalInfoRoot>
请注意,在外部文档中,目标元素的名称是大写的,我无法控制它,并且由于“LEVEL_1/ITEM_3”之类的原因,我需要在根的完整 xpath 中使用 contains。
这个解决方案有效,但它有点麻烦,我认为必须有一个更好的解决方案,我无法设计......
非常欢迎任何改进这一点的建议或提示!
感谢 Vlax