Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.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
XSLT:使用一个属性合并两个标记,使用转换/映射合并另一个标记_Xslt - Fatal编程技术网

XSLT:使用一个属性合并两个标记,使用转换/映射合并另一个标记

XSLT:使用一个属性合并两个标记,使用转换/映射合并另一个标记,xslt,Xslt,我在输入文件中有两个标记,变量和类型: <variable baseType="int" name="X"> </variable> <type baseType="structure" name="Y"> <variableInstance name="X" /> </type> 我需要生成以下输出文件: <Item name="Y"> <Field name="X" type="Long"

我在输入文件中有两个标记,变量和类型:

<variable baseType="int" name="X">
</variable>

<type baseType="structure" name="Y">
    <variableInstance name="X" />
</type>

我需要生成以下输出文件:

<Item name="Y">
    <Field name="X" type="Long" />
</Item>

因此,从概念上讲,我的方法是将type标记转换为Item tage,将变量实例转换为字段。这很好:

<xsl:for-each select="type[@baseType='structure']">
    <Item>
        <xsl:attribute name="name"><xsl:value-of select="@name" /></xsl:attribute>
        <xsl:for-each select="variableInstance">
            <Field>
                <xsl:attribute name="name"><xsl:value-of select="@name" /></xsl:attribute>
                <xsl:attribute name="type">**THIS IS WHERE I'M STUCK**</xsl:attribute>
            </Field>
        </xsl:for-each>
    </Item>
</xsl:for-each>

**这就是我被困的地方**
我遇到的问题是:

  • 我不知道如何让variableInstance/Field标记按名称与变量标记匹配,这样我就可以访问baseType了
  • 一旦我能做1,我需要将“int”映射到“Long”
  • 提前谢谢

    问题1

    对于您遇到的第一个问题,您可以使用密钥:

    <xsl:key name="variable-key" match="//variable" use="@name" />
    
    当您有很多可变元素时,使用这种方法是有效的

    注意:如果每个变量都有自己的作用域(即,您有在文档的不同部分不可见的局部变量),则此方法无效。在这种情况下,应修改此方法

    问题2

    对于映射属性,可以使用如下模板:

        <xsl:template match="@baseType[. = 'int']">
            <xsl:attribute name="baseType">
                <xsl:value-of select="'Long'" />
            </xsl:attribute>
        </xsl:template>
    
    
    
    这种转换的意义是:每次我们将一个baseType属性与int值匹配时,它都必须被一个长值替换

    对于文档中的每个@baseType属性,都将进行此转换


    使用所述策略,解决方案可以是:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
        <xsl:output method="xml" indent="yes" />
    
        <!-- Index all variable elements in the document by name -->
        <xsl:key name="variable-key"
                 match="//variable"
                 use="@name" />
    
        <!-- Just for demo -->
        <xsl:template match="text()" />
    
        <!-- Identity template: copy attributes by default -->
        <xsl:template match="@*">
            <xsl:copy>
                <xsl:value-of select="." />
            </xsl:copy>
        </xsl:template>
    
        <!-- Match the structure type -->
        <xsl:template match="type[@baseType='structure']">
            <Item>
                <xsl:apply-templates select="*|@*" />
            </Item>
        </xsl:template>
    
        <!-- Match the variable instance -->
        <xsl:template match="variableInstance">
            <Field>
                <!-- Use the key to find the variable with the current name -->
                <xsl:apply-templates select="@*|key('variable-key', @name)/@baseType" />
            </Field>
        </xsl:template>
    
       <!-- Ignore attributes with baseType = 'structure' -->
        <xsl:template match="@baseType[. = 'structure']" />
    
        <!-- Change all baseType attributes with long values to an attribute
            with the same name but with an int value  -->
        <xsl:template match="@baseType[. = 'int']">
            <xsl:attribute name="baseType">
                <xsl:value-of select="'Long'" />
            </xsl:attribute>
        </xsl:template>
    
    </xsl:stylesheet>
    
    
    
    该代码将转换以下XML文档:

    <!-- The code element is present just for demo -->
    <code>
        <variable baseType="int" name="X" />
        <type baseType="structure" name="Y">
            <variableInstance name="X" />
        </type>
    </code>
    
    
    
    
    
    进入

    
    
    好的,我已经为第1点或第2点找到了解决方案。对于第二点,我可能会使用与Pablo Pozo在回答中使用的模板类似的模板

    嘿,Pablo,太好了。我对xsl:key标记缺乏了解,这是阻止我前进的原因。我的代码中的一个快速黑客现在正在工作。非常感谢!干杯,很高兴我能帮忙。
    <!-- The code element is present just for demo -->
    <code>
        <variable baseType="int" name="X" />
        <type baseType="structure" name="Y">
            <variableInstance name="X" />
        </type>
    </code>
    
    <Item name="Y">
        <Field baseType="Long" name="X"/>
    </Item>