【问题标题】:Child node attribute in XSLTXSLT 中的子节点属性
【发布时间】:2010-12-07 20:29:00
【问题描述】:

是否可以在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>

感谢您的帮助。

【问题讨论】:

  • 是的。请提供更多详细信息,例如示例 XML 文档以及您到目前为止所做的尝试。
  • 请提供完整的所需输出。
  • 这个一点都不清楚。首先,XSLT 中的典型标题/数据句柄涉及模式的使用。其次,您正在对所有记录进行一些存在性比较:“是否有 any @fieldName 等于 'dtrk_sysid' 和 any @fieldValue 不等于 0?”

标签: xslt


【解决方案1】:

以下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”的&lt;FieldValue&gt; 的@fieldValue,但没有什么可以限制第二次比较特别是&lt;FieldValue&gt;。 &lt;xsl:if test=...&gt; 没有设置上下文。然后&lt;xsl:value-of&gt; 将在您的示例输入 XML 中选择上下文节点下所有 Record/FieldValue 节点的 first @fieldValue 属性,幸运的是,这恰好是正确的属性(但可能并非总是如此? )。

要解决此问题,您可以在变量中捕获上下文(&lt;FieldValue&gt;,其@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>

(以上已修改以适应 cmets 中描述的行为。)

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

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

如果不存在这样的 FieldValue,则不会输出任何内容。

如果在此之后您仍然没有得到想要的输出,请告诉我们您得到了什么输出,以及它与想要的输出有何不同。

【讨论】:

  • @LarsH:谢谢你帮助我。很抱歉回复晚了,远离电脑。我只是运行测试。 WHEN 语句中的条件无法正常工作。如果 它返回“55555”,但如果 fieldValue="0" 它返回“0”。所以它不会默认。
  • @klipa,尝试将 != 0 改回 != '0',就像原来的那样。
  • @klipa:您能否编辑以显示具有您刚才提到的结果的更新 XSLT?
  • @LarsH,我更新了 XML 和 XSLT。实际上“dtrk_sysid”存在于每个记录中,而不是第一个位置。很抱歉误导了你。
  • @klipa,好的,我现在明白为什么它不起作用了。但我不确定上述输入的正确行为应该是什么。如果有n条不同的记录,其中有几条的dtrk_sysid fieldValue属性不是“0”,你要输出哪一条?我将编辑我的答案,使其输出第一个非零值,但我不知道这是否是您想要的行为。
猜你喜欢
  • 1970-01-01
  • 2017-07-11
  • 1970-01-01
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 2021-10-21
  • 2010-10-26
  • 2012-08-03
相关资源
最近更新 更多