Элемент соответствия XSL, основанный на значении - PullRequest
1 голос
/ 21 октября 2010

Я преобразовываю XML, в котором я должен найти определенный элемент (на основе значения атрибута) и обновить элемент и его дочерние атрибуты.

Пример файла XML приведен ниже.

<?xml version="1.0" encoding="utf-8"?>
<Configuration>
    <Environments>
        <Environment id="Master"/>
        <Environment id="Developer"/>
    </Environments>
    <Common>
        <Logging>
            <LogFile>log\updater.log</LogFile>
        </Logging>
    </Common>
<Configuration>

Мой XSLT-файл показан ниже.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes"/>
    <xsl:param name="EnvironmentId" />
    <xsl:param name="SelectEnvironment" />
    <!-- Copy All Elements -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <!-- Modify Element with id = Developer-->
    <xsl:template match="Environment/@id[. ='Developer']">
        <xsl:attribute name="id">
            <xsl:value-of select="$EnvironmentId"/>
        </xsl:attribute>
    </xsl:template>

</xsl:stylesheet>

В этом XSLT переменная EnvironmentId содержит новый идентификатор; переменная SelectEnvironment должна содержать значение Developer (или любое другое предоставленное пользователем значение, передаваемое через C # .NET)

Вопрос

Как мне написать свой XSLT, чтобы совпадение работало на основе пользовательского значения?

Я попробовал следующее

<xsl:template match="Environment/@id[. ='$SelectEnvironment']">
    <xsl:attribute name="id">
        <xsl:value-of select="$EnvironmentId"/>
    </xsl:attribute>
</xsl:template>

Нет ошибок. Но идентификатор attr не был обновлен.

Я пробовал это ...

<xsl:template match="Environment/@id[. =$SelectEnvironment]">
    <xsl:attribute name="id">
        <xsl:value-of select="$EnvironmentId"/>
    </xsl:attribute>
</xsl:template>

И я получил ошибку времени выполнения Переменные не могут быть использованы в этом выражении.

Ответы [ 2 ]

2 голосов
/ 21 октября 2010

Вы не можете иметь переменные в шаблонах совпадений;их можно сравнить со временем компиляции.Ответ на вашу загадку заключается в том, чтобы вывести логику из игры (и, возможно, потерять небольшой штраф в производительности).Не проверено;

<xsl:template match="Environment/@id">
   <xsl:if test="[.=$SelectEnvironment]">
      <xsl:attribute name="id">
         <xsl:value-of select="$EnvironmentId"/>
      </xsl:attribute>
   </xsl:if>
</xsl:template>

Однако есть и другие, лучшие и более быстрые способы решения вашей проблемы, которые, вероятно, можно объяснить немного лучше, чем то, на что указывает ваша проблема в примере?

Вот мой полный XSLTвыполняет то, что вы хотите, полностью протестировано (является ли пропущенное закрытие элемента ошибкой в ​​копировании-вставке?);

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes"/>
    <xsl:param name="EnvironmentId" />
    <xsl:param name="SelectEnvironment" />
    <!-- Copy All Elements -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <!-- Modify Element with id = Developer-->
    <xsl:template match="Environment">
        <xsl:choose>
            <xsl:when test="@id=$SelectEnvironment">
                <Environment id="{$EnvironmentId}" />
            </xsl:when>
            <xsl:otherwise>
                <Environment id="{@id}" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>
1 голос
/ 21 октября 2010

Я пробовал это ...

     <xsl:template match="Environment/@id[.
 =$SelectEnvironment]"> 
         <xsl:attribute name="id"> 
             <xsl:value-of select="$EnvironmentId"/> 
         </xsl:attribute> 
     </xsl:template>

И я получил ошибку во время выполнения Переменные не могут быть использованы в этом выражение.

В XSLT 1.0 выражение соответствия не может содержать ссылку на переменную или параметр. Это было сделано с целью предотвращения круговых определений.

Однако в XSLT 2.0 они разрешены в шаблоне совпадений .

Следовательно, вы можете сделать это, используя XSLT 2.0.

Для некоторых людей XSLT 2.0 все еще далекая мечта - тогда вы всегда можете сделать так, как рекомендовано в принятом ответе.

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