Атрибут дочернего узла в XSLT - PullRequest
2 голосов
/ 07 декабря 2010

Можно ли получить доступ к атрибутам дочерних узлов в xsl: если

Мне нужно преобразовать этот 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 Ответ

4 голосов
/ 08 декабря 2010

Основная проблема со следующим оператором if:

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

состоит в том, что @fieldValue, который вы пытаетесь сравнить после and, должен быть @fieldValue <FieldValue>, чье @fieldName равно 'dtrk_sysid', но ничто не ограничивает второе сравнение этим частный <FieldValue>. <xsl:if test=...> не устанавливает контекст. <xsl:value-of> затем выберет атрибут first @fieldValue для всех узлов Record / 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 не существует.

Если после этого вы все еще не получаете желаемый результат, сообщите нам, какой выход вы получаете, и чем он отличается от желаемого результата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...