0

我有一个包含多个 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 并更改其节点的值。

谢谢。

4

1 回答 1

0

我不确定这样的事情在 XSL 2.0 中是否可行。可能在 3.0 中应该有一些函数 evaluate() 但我不知道任何细节。

但是我尝试了一些解决方法,它似乎可以正常工作。当然,它并不完美,这种形式有很多限制(例如,您需要指定绝对路径,不能使用更复杂的 XPath,如 //、[] 等),因此仅将其视为一个想法。但在一些更简单的情况下,这可能是一种方式。

它基于比较两个字符串而不是评估字符串作为 XPath。

使用 xpaths 加密的简化 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>
于 2013-06-05T06:11:18.170 回答