我有一个大的XML文件,我需要改变其中的某些值,其中ID号(OWNINST)与另一个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>
或者,我可以运行多个样式表,一次将数据放在一个节点中,即在一个样式表中更新MODE,在另一个样式表中更新MCDATE等
多谢
编辑:22/9/2015
Abel,谢谢你的帮助。它似乎只是复制原始文件,而没有做任何修改。
它会帮助如果我可以结构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>
这是我现在的代码
<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>
我将更改最后一位代码的哪一部分以针对特定节点,例如模式?
感谢编辑1:45pm 22/09/15
我想看到的输出是:
<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>
多谢
它会帮助如果我可以结构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>
是的,那样会方便得多。试试这样:
XSLT 1.0<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>
<xsl:template match="Student/Instance[OWNINST = document('File2.xml')/studentstoamend/OWNINST]/MODE">
这将不匹配任何东西,您的输入文件有student
和instance
作为元素名,XML是区分大小写的。
在此模板中,将模板应用于原始文档(File1.xml)。要采用来自File2.xml的更改,您必须将模板应用于第二个文档,即以下内容:
<xsl:variable name="students2" select="document('File2.xml')/studentstoamend" />
<xsl:template match="student/instance[OWNINST = document('File2.xml')/studentstoamend/OWNINST]">
<xsl:variable name="owninst" select="OWNINST" />
<xsl:copy>
<xsl:apply-templates select="$students2[OWNINST = $owninst]/*" mode="file2" />
</xsl:copy>
</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>
更新:将主模板的焦点从MODE
改为OWNINST