Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 基于值的XSL匹配元素_C#_Xml_Xslt - Fatal编程技术网

C# 基于值的XSL匹配元素

C# 基于值的XSL匹配元素,c#,xml,xslt,C#,Xml,Xslt,我正在转换一个XML,在这里我应该定位一个特定的元素(基于属性值)并更新元素及其子属性 示例XML文件如下所示 <?xml version="1.0" encoding="utf-8"?> <Configuration> <Environments> <Environment id="Master"/> <Environment id="Developer"/> </Environm

我正在转换一个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>
<?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>

log\updater.log
我的XSLT文件如下所示

<?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>
<?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包含新的id;变量SelectEnvironment应包含value Developer(或通过C#.NET传递的任何其他用户提供的值)

问题

如何编写XSLT以使匹配基于用户定义的值工作

我尝试了以下方法

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

没有错误。但是,属性id没有更新

我试过这个

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


我得到了一个运行时错误,变量不能在这个表达式中使用

模板匹配中不能有变量;它们可以与编译时进行比较。你的难题的答案是将逻辑从比赛中移开(也许会在表现上损失一点点球)。未经测试

<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,它可以实现您想要的功能,经过了全面测试(元素缺少关闭是复制粘贴中的一个错误吗?)


我试过这个

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

我得到了一个运行时错误 在此范围内不能使用变量 表情

在XSLT1.0中,匹配表达式不能包含对变量或参数的引用。这样做的目的是防止循环定义

但是在XSLT2.0中

因此,您可以使用XSLT2.0来实现这一点


对于一些人来说,XSLT2.0仍然是一个遥远的梦想——那么你可以按照公认答案中的建议去做。

@AlexanderJohannesen:谢谢!我的XSLT技能是有限的(只有一天!),在代码的第二行…您正在关闭;你为什么要把它作为最后一行关闭呢?此外,即使我删除xsl:if命令的关闭,此代码的复制粘贴也不起作用。任何需要修改的东西。对不起,第一个不应该关闭。在代码示例中修复了它,并添加了最后一个示例。@AlexanderJohannesen:很抱歉,这让人很痛苦。完整的XSLT不会根据变量选择环境,而是选择id value=Developer的环境。可能是复制粘贴错误?第二,我不确定你指的是哪个缺失的冒号。第三,我们删除的修改后的XSLT也不起作用。它抛出了一个错误,这是一个意外的标记'[“在表达式中,是的,是错误的复制”“粘贴。更新了示例,它做了您想要的事情,尽管我怀疑这是一个非常好的解决方案。最好解释问题空间到底是什么,并看看是否有更好的方法来解决它。@AlexanderJohannesen:您的答案仅适用于过时版本的XSLT--1.0.Pl简单地说,不要将语句一般标记为“在XSLT中”,而是说:“在XSLT1.0中”。所有这些都说明,是的,这是一个非常好的答案。好问题。请参阅我的答案,以获得解释和建议,使用更新版本的XSLT,从而消除问题。这不是问题的答案,更新XSLT可能不是一个选择。@HosseinShahdoost,升级到XSLT 2.0甚至在5年前也是一个选择。今天,在使用Saxon CE,XSLT 2.0的g是一种标准——它甚至可以在iPhone和任何带有Javascript的手机上使用。这个答案提供了对于仍然落后的人来说特别重要的信息。另外,请注意,这个问题没有标记为“XSLT-1.0”!因此,您的否决票是不合理的。如果您使用的是使用XSLT的工具,并且在该工具中无需更新XSLT库,那么这可能不是一个选择。顺便说一句,我尝试删除否决票,但15小时规则不允许我更改我的投票。