我有一个带有多个Xpath列表的外部文档,如下所示:
<EncrypRqField>
<EncrypFieldRqXPath01>xpath1</EncrypFieldRqXPath01>
<EncrypFieldRqXPath02>xpath2</EncrypFieldRqXPath02>
</EncrypRqField>
我使用这个文档来获取我想要修改的节点的Xpath。
输入XML是:
<Employees>
<Employee>
<id>1</id>
<firstname>xyz</firstname>
<lastname>abc</lastname>
<age>32</age>
<department>xyz</department>
</Employee>
</Employees>
我想获得这样的东西:
<Employees>
<Employee>
<id>XXX</id>
<firstname>xyz</firstname>
<lastname>abc</lastname>
<age>XXX</age>
<department>xyz</department>
</Employee>
</Employees>
XXX值是数据加密的结果,我想从文档中动态获取Xpath并更改其节点的值。
感谢。
答案 0 :(得分:0)
我不确定在XSL 2.0中是否可以使用这样的东西。可能在3.0中应该有一些函数evaluate()但我不知道任何细节。
但我尝试了一些解决方法,似乎功能正常。当然它并不完美,并且在这种形式中有很多限制(例如,你需要指定绝对路径,你不能使用更复杂的XPath,如//,[]等),所以考虑它只是一个想法。但它可能是一些更容易的案例。
它基于比较两个字符串而不是评估字符串作为XPath。
带有要加密的xpath的简化xml(为简单起见,我省略了数字)。
<?xml version="1.0" encoding="UTF-8"?>
<EncrypRqField>
<EncrypFieldRqXPath>/Employees/Employee/id</EncrypFieldRqXPath>
<EncrypFieldRqXPath>/Employees/Employee/age</EncrypFieldRqXPath>
</EncrypRqField>
我的转变
<xsl:template match="element()">
<xsl:variable name="pathToElement">
<xsl:call-template name="getPath">
<xsl:with-param name="element" select="." />
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$xpaths/EncrypFieldRqXPath[text() = $pathToElement]">
<!-- If exists element with exacty same value as constructed "XPath", ten "encrypt" the content of element -->
<xsl:copy>
<xsl:text>XXX</xsl:text>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- This template will "construct" the XPath for element under investigation. -->
<!-- There might be an easier way (e.g. some build-in function), but it is actually out of my skill. -->
<xsl:template name="getPath">
<xsl:param name="element" />
<xsl:choose>
<xsl:when test="$element/parent::node()">
<xsl:call-template name="getPath">
<xsl:with-param name="element" select="$element/parent::node()" />
</xsl:call-template>
<xsl:text>/</xsl:text>
<xsl:value-of select="$element/name()" />
</xsl:when>
<xsl:otherwise />
</xsl:choose>
</xsl:template>
</xsl:stylesheet>