XSLT中的子节点属性

时间:2010-12-07 20:29:01

标签: xslt

是否可以在 xsl:if

中访问子节点属性

我必须将该Xml转换为文本文件

<Report>
<Total>
    <RecordValues>
        <Record>
        <FieldValue fieldName="index"       fieldValue="1" />
        <FieldValue fieldName="dtrk_sysid" fieldValue="0"/>
        <FieldValue fieldName="version"     fieldValue="100" />
        <FieldValue fieldName="user"        fieldValue="tester" />
        <FieldValue fieldName="date_modified"   fieldValue="2010-10-18 12:18:12" />
        <FieldValue fieldName="object_name"     fieldValue="Menu" />
        <FieldValue fieldName="permission"  fieldValue="Permission X" />
        </Record>
        <Record>
        <FieldValue fieldName="index"       fieldValue="2" />
        <FieldValue fieldName="dtrk_sysid" fieldValue="55555"/>
        <FieldValue fieldName="version"     fieldValue="100" />
        <FieldValue fieldName="user"        fieldValue="user1" />
        <FieldValue fieldName="date_modified"   fieldValue="2010-12-15 12:18:12" />
        <FieldValue fieldName="object_name"     fieldValue="Control" />
        <FieldValue fieldName="permission"  fieldValue="Permission E" />
        </Record>
        <Record>
        <FieldValue fieldName="index"       fieldValue="3" />
        <FieldValue fieldName="dtrk_sysid" fieldValue="55555"/>
        <FieldValue fieldName="version"     fieldValue="15" />
        <FieldValue fieldName="user"        fieldValue="user2" />
        <FieldValue fieldName="date_modified"   fieldValue="2010-10-02 12:18:12" />
        <FieldValue fieldName="object_name"     fieldValue="Run" />
        <FieldValue fieldName="permission"  fieldValue="Permission R" />
        </Record>
    </RecordValues>
</Total>

我已经知道怎么做了,但是文件必须有头记录,它应该只出现一次作为文件的第一个记录。它必须包含一些默认值和 FieldValue 节点中的一些值。 以下是标题记录的示例:

HDRTT55555EE000KK20101018UU
1 100  101810
tester  Menu       Permission X
2 100  121510
user1   Control    Permission E
3 15   100210
user2   Run        Permission R 

这是我到目前为止所做的:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes" encoding="UTF-8" omit-xml-   declaration="yes"/>

<xsl:template match="/">
    <xsl:apply-templates select="/Report/Total/RecordValues"/>
    <xsl:apply-templates select="/Report/Total/RecordValues/Record/FieldValue"/>
</xsl:template>
<xsl:template match="RecordValues">
    <xsl:text>HDR</xsl:text>
    <xsl:text>TT</xsl:text>
    <xsl:variable name="fvsys" select="Record/FieldValue[@fieldName = 'dtrk_sysid']"/>
    <xsl:choose>
        <xsl:when test="$fvsys/@fieldValue != '0'">
            <xsl:value-of select="$fvsys/@fieldValue"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:text>12343</xsl:text>
        </xsl:otherwise>
    </xsl:choose>
    <xsl:text>EE</xsl:text>
    <xsl:text>000</xsl:text>
    <xsl:text>KK</xsl:text>
            <xsl:if test="Record/FieldValue[@fieldName='date_modified']">
        <xsl:call-template name="ppad">
            <xsl:with-param name="str" select="concat(substring(translate(Record/FieldValue[@fieldName = 'date_modified']/@fieldValue,'-',''),5,4), substring(Record/FieldValue[@fieldName = 'date_modified']/@fieldValue,3,2))"/>
            <xsl:with-param name="len" select="6"/>
        </xsl:call-template>
    </xsl:if>
    <xsl:text>UU</xsl:text>
    <xsl:text>&#xA;</xsl:text>
</xsl:template>

<xsl:template match="FieldValue">

</xsl:template>

<xsl:template name="ppad">
    <xsl:param name="str"/>
    <xsl:param name="chr" select="' '"/>
    <xsl:param name="len" select="0"/>
    <xsl:choose>
        <xsl:when test="string-length($str) &lt; $len">
            <xsl:call-template name="ppad">
                <xsl:with-param name="str" select="concat($str, $chr)"/>
                <xsl:with-param name="len" select="$len"/>
                <xsl:with-param name="chr" select="$chr"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$str"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
</xsl:stylesheet>

感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

以下if语句的主要问题:

<xsl:if test="Record/FieldValue/@fieldName='dtrk_sysid' and Record/FieldValue/@fieldValue!='0'">
    <xsl:value-of select="Record/FieldValue/@fieldValue"/>
</xsl:if>

是你在and应该是<FieldValue> @fieldName为'dtrk_sysid'的@fieldValue之后你想要比较的@fieldValue,但没有任何限制与该特定<FieldValue>的第二次比较。 <xsl:if test=...>未设置上下文。然后,<xsl:value-of>将在上下文节点下选择所有Record / FieldValue节点的第一个 @fieldValue属性,这在运动样本输入XML中可能是正确的(但可能不是总是?)。

要解决此问题,您可以在变量中捕获上下文(<FieldValue>,其中@fieldName是'dtrk_sysid'):

  <xsl:variable name="fvsys" select="(Record/FieldValue[@fieldName = 'dtrk_sysid'])[1]"/>

然后你可以用前面的两个if语句替换:

  <xsl:choose>
     <xsl:when test="$fvsys/@fieldValue != '0'">
        <xsl:value-of select="$fvsys/@fieldValue"/>
     </xsl:when>
     <xsl:otherwise>
        <xsl:text>12343</xsl:text>
     </xsl:otherwise>
  </xsl:choose>

(以上内容已经过修改,以适应评论中描述的行为。)

您可以将第三个if语句替换为:

 <xsl:value-of select="(Record/FieldValue[@fieldName = 'date_modified'])[1]/@fieldValue"/>

如果不存在此类FieldValue,则不会输出任何内容。

如果在此之后你还没有得到所需的输出,请告诉我们你得到了什么输出,以及它与所需输出的不同。