将一个XML文件中的多个值更改为另一个XML文件中引用的值
我有一个很大的XML文件,需要更改其中的某些值,其中ID号ownist与另一个XML文件中的一个匹配 我的大型XML文件“file1.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>
<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>