我有一个大型XML文件,我需要更改其中ID号(OWNINST)与另一个XML文件中的ID匹配的某些值。
我的大型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等等
非常感谢
编辑:2015年9月22日
感谢您的帮助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:24 pm 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>
非常感谢
答案 0 :(得分:0)
<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
。
答案 1 :(得分:0)
如果我可以按如下方式构建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>