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
将一个XML文件中的多个值更改为另一个XML文件中引用的值_Xml_Xslt_Xslt 1.0 - Fatal编程技术网

将一个XML文件中的多个值更改为另一个XML文件中引用的值

将一个XML文件中的多个值更改为另一个XML文件中引用的值,xml,xslt,xslt-1.0,Xml,Xslt,Xslt 1.0,我有一个很大的XML文件,需要更改其中的某些值,其中ID号ownist与另一个XML文件中的一个匹配 我的大型XML文件“file1.XML”的格式如下: <institution> <ukprn>1234</ukprn> <course> <courseID>1</courseID> <courseaim>X99</courseaim>

我有一个很大的XML文件,需要更改其中的某些值,其中ID号ownist与另一个XML文件中的一个匹配

我的大型XML文件“file1.XML”的格式如下:

    <institution>
    <ukprn>1234</ukprn>
    <course>
        <courseID>1</courseID>
        <courseaim>X99</courseaim>
    </course>
    <student>
        <birthdate>30/10/1985</birthdate>
        <instance>
            <OWNINST>123456|5</OWNINST>
            <FC>1</FC>
            <STULOAD>100</STULOAD>
            <elq>4</elq>
            <MODE>31</MODE>
        </instance>
    </student>
    <student>
        <birthdate>01/02/1999</birthdate>
        <instance>
            <OWNINST>654321|1</OWNINST>
            <FC>2</FC>
            <elq>2</elq>
        </instance>
        <instance>
            <OWNINST>654321|2</OWNINST>
            <FC>6</FC>
            <elq>1</elq>
        </instance>
    </student>
</institution>
有多个学生,每个学生都可以有多个实例

我有另一个xml文件“File2.xml”,其结构如下:

<studentstoamend>
<OWNINST>123456|5</OWNINST><MODE>01</MODE><STULOAD>100</STULOAD>
<OWNINST>111112|1</OWNINST><MODE>31</MODE><STULOAD>75</STULOAD>
</studentstoamend>
对于File2.xml中的每个学生,我想将File1.xml中字段的值更改为File2.xml中列出的值。不应更改File2.xml中未列出的任何学生

请找个人帮忙,因为我似乎做不到

这就是我取得的成绩:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/>
<xsl:strip-space elements="*"/>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>        
    </xsl:copy>
</xsl:template>

<xsl:template match="Student/Instance[OWNINST = document('File2.xml')/studentstoamend/OWNINST]/MODE">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>        
    </xsl:copy>
</xsl:template>
或者,我可以运行多个样式表,一次将数据放在一个节点中,即一个样式表中的更新模式和另一个样式表中的MCDATE等

非常感谢

编辑:22/9/2015

谢谢你的帮助,亚伯。它似乎只是复制了原始文件,但没有进行修改

如果我能按如下方式构造file2.xml,会有帮助吗

<?xml version="1.0" encoding="UTF-8"?>
<studentstoamend>
    <student><OWNINST>328352|2</OWNINST><MODE>31</MODE><STULOAD>50</STULOAD><MCDATE>12/01/2015</MCDATE></student>
    <student><OWNINST>652508|3</OWNINST><MODE>01</MODE><STULOAD>100</STULOAD><MCDATE>15/11/2014</MCDATE></student>
</studentstoamend>
<?xml version="1.0" encoding="UTF-8"?>
<studentstoamend>
    <student><OWNINST>328352|2</OWNINST><MODE>31</MODE><STULOAD>50</STULOAD><MCDATE>12/01/2015</MCDATE></student>
    <student><OWNINST>652508|3</OWNINST><MODE>01</MODE><STULOAD>100</STULOAD><MCDATE>15/11/2014</MCDATE></student>
</studentstoamend>
这就是我现在拥有的代码

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>        
    </xsl:copy>
</xsl:template>

<xsl:variable name="students2" select="document('File2.xml')/studentstoamend" />

<xsl:template match="student/instance[OWNINST = document('File2.xml')/studentstoamend/OWNINST]/MODE">
    <xsl:variable name="owninst" select="OWNINST" />
    <xsl:apply-templates select="$students2[OWNINST = $owninst]/*" mode="file2" />
</xsl:template>

<!-- adjust this, or add more templates in this mode if changes in element names/values are needed -->
<xsl:template match="node() | @*" mode="file2">
    <xsl:copy>
        <xsl:apply-templates select="node() | @*" mode="file2" />
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
最后一段代码的哪一部分将更改为目标特定节点,例如模式

谢谢

2015年9月22日下午1:45编辑

我希望看到的结果是:

    <institution>
    <ukprn>1234</ukprn>
    <course>
        <courseID>1</courseID>
        <courseaim>X99</courseaim>
    </course>
    <student>
        <birthdate>30/10/1985</birthdate>
        <instance>
            <OWNINST>123456|5</OWNINST>
            <FC>1</FC>
            <STULOAD>100</STULOAD> <!--Updated to 100 (although in this case it already was 100 so no change) -->
            <elq>4</elq>
            <MODE>01</MODE> <!--Updated to 01 -->
        </instance>
    </student>
    <student>
        <birthdate>01/02/1999</birthdate>
        <instance>
            <OWNINST>654321|1</OWNINST>
            <FC>2</FC>
            <elq>2</elq>
        </instance>
        <instance>
            <OWNINST>654321|2</OWNINST>
            <FC>6</FC>
            <elq>1</elq>
        </instance>
    </student>
</institution>
非常感谢

更新:将主模板的焦点从模式更改为OWNINST

如果我能按如下方式构造file2.xml,会有帮助吗

<?xml version="1.0" encoding="UTF-8"?>
<studentstoamend>
    <student><OWNINST>328352|2</OWNINST><MODE>31</MODE><STULOAD>50</STULOAD><MCDATE>12/01/2015</MCDATE></student>
    <student><OWNINST>652508|3</OWNINST><MODE>01</MODE><STULOAD>100</STULOAD><MCDATE>15/11/2014</MCDATE></student>
</studentstoamend>
<?xml version="1.0" encoding="UTF-8"?>
<studentstoamend>
    <student><OWNINST>328352|2</OWNINST><MODE>31</MODE><STULOAD>50</STULOAD><MCDATE>12/01/2015</MCDATE></student>
    <student><OWNINST>652508|3</OWNINST><MODE>01</MODE><STULOAD>100</STULOAD><MCDATE>15/11/2014</MCDATE></student>
</studentstoamend>
是的,那样会方便得多。试着这样做:

XSLT1.0


谢谢你,亚伯。我尝试了这个,它只是删除了所有节点,只保留了旧值,而不是新值。我在上面进行了编辑,以反映您建议的更改以及我关于调整最后一部分的问题。谢谢Abel,一如既往地非常有用。@MartinB,现在还不完全清楚您到底想要输出什么,但是学生/实例模板的焦点是模式,所以它没有自己的子对象。我改了,看更新。根据您希望从原始文件和额外文件复制的数据,您必须进行额外的调整。我对它进行了测试,数据现在是从额外文件复制的。@MartinB如果您想要原始文件中的所有数据,以及第二个文件中的一些数据,您可以在模式中保留模式,但随后将变量$owninst更改为select../owninst,或者在默认模式下添加一个额外的应用模板。是否保留其他文件中没有相应字段的字段,例如示例的第一个实例中的1?还是要替换整个实例?我只想更新该实例的文件2中列出的字段。因此,例如在File1.xml OWNINST 123456中,5的模式为31,STULOAD为100。File2.xml中的值分别为01和100,因此我只想修改File1.xml中的这些值。恐怕规则还不完全清楚。要修改的字段是否总是这两个:MODE和STULOAD?换句话说,这两个名称可以在样式表中硬编码吗?或者File2中的节点是否可以包含任何字段的混合?如果是后者,是否有一个所有可能字段的列表?它将始终是mode和stuload,因此它们可以硬编码。这工作非常完美,非常感谢michael.hor257k和Abel为您提供的所有帮助。但它仍然不允许我单击向上箭头。很抱歉,我花了一些时间来解释我想要什么,但谢谢你坚持我。
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="instance">
    <xsl:variable name="amend" select="document('File2.xml')/studentstoamend/student[OWNINST=current()/OWNINST]"/>
    <xsl:copy>
        <xsl:choose>
            <xsl:when test="$amend">
                <xsl:apply-templates select="@*|node()[not(self::MODE or self::STULOAD)]"/>
                <xsl:apply-templates select="$amend/MODE | $amend/STULOAD"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>