XSLT XPath,需要根据兄弟节点的数值更改节点值

时间:2014-06-25 22:13:39

标签: xslt xpath

我试图通过检查以下节点是否包含奇数或偶数来尝试将节点值更改为两个不同的东西之一。

这是源XML。

<?xml version="1.0" encoding="UTF-8"?>
<FILE>
<CLAIM>
<PERSON>
<PROVIDER>
<HEADER>
<FLAG>PPON</FLAG>
<IDNO>11612</IDNO>
</HEADER>
</PROVIDER>
</PERSON>
</CLAIM>
</FILE>

我正在尝试的XSLT是:

    <?xml version='1.0' ?>
<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output 
        method="xml" 
        version="1.0" 
        encoding="UTF-8" 
        indent="yes" 
        omit-xml-declaration="no"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="FLAG/node()">
        <xsl:choose>
            <xsl:when test="number(../IDNO) mod 2 = 0">EVEN</xsl:when>
            <xsl:otherwise>ODD</xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

我想输出的是

<?xml version="1.0" encoding="UTF-8"?>
<FILE>
<CLAIM>
<PERSON>
<PROVIDER>
<HEADER>
<FLAG>EVEN</FLAG>
<IDNO>11612</IDNO>
</HEADER>
</PROVIDER>
</PERSON>
</CLAIM>
</FILE>

我知道我在测试时没有得到IDNO,因为我的代码一直给我ODD,同时在调试时我尝试将when测试的值放入FLAG并获得NaN。但是我无法想出正确的语法来让IDNO进入测试阶段。

是的,我是XSLT的新手,所以也许这是一个愚蠢的问题,但我尝试了很多不同的东西,并搜索了这个网站和其他人的答案,没有运气。

提前感谢您的帮助。

DWL

2 个答案:

答案 0 :(得分:2)

您当前模板匹配 FLAG

的子项
<xsl:template match="FLAG/node()">

现在,当您使用..时,这是在查找父级,因此..会在此上下文中匹配 FLAG ,因此../IDNO正在寻找标识的孩子名为 IDNO ,不存在。

你需要再提高一级。试试这个

<xsl:template match="FLAG/text()">
    <xsl:choose>
        <xsl:when test="number(../../IDNO) mod 2 = 0">EVEN</xsl:when>
        <xsl:otherwise>ODD</xsl:otherwise>
    </xsl:choose>
</xsl:template>

答案 1 :(得分:0)

可能更容易检查节点的轴,而不是节点本身:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="http://www.mycompany.com/services/core/file" exclude-result-prefixes="a">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="no"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="*">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="IDNO">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:choose>
                <xsl:when test="number(.) mod 2 = 0">EVEN</xsl:when>
                <xsl:otherwise>ODD</xsl:otherwise>
            </xsl:choose>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>