我正在尝试通过将它们与外部文件中的elements属性相匹配来替换/修改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>
请注意,在外部文档中,目标元素的名称是大写的,我无法控制它,我需要在完整的xpath中使用contains到root,因为像“LEVEL_1 / ITEM_3”这样的东西”
这个解决方案正在运行,但它有点麻烦,我认为必须有一个更好的解决方案,我无法设计......
非常欢迎任何改进此建议或提示!
Thxs 明经
答案 0 :(得分:0)
这可能更简单:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vLookupDoc">
<t>
<e path="ITEM_1">111111</e>
<e path="LEVEL_1/ITEM_3">333333</e>
</t>
</xsl:variable>
<xsl:template match="node()[not(self::text())]|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:variable name="vRep" select=
"$vLookupDoc/*/e
[ends-with(
string-join(current()/ancestor::*[parent::*]/lower-case(name(.)), '/'),
lower-case(@path)
)
]
/string(.)
"/>
<xsl:sequence select="(., $vRep)[last()]"></xsl:sequence>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<root>
<level_1>
<item_1>xxxxx</item_1>
<item_2>yyyyy</item_2>
<item_3>zzzzz</item_3>
</level_1>
</root>
产生了想要的正确结果:
<root>
<level_1>
<item_1>111111</item_1>
<item_2>yyyyy</item_2>
<item_3>333333</item_3>
</level_1>
</root>