我想要合并两个xml文件。我正在使用OXYGEN软件通过XML Sytlesheets来做到这一点。文件2向文件1添加了更多细节,为每个需要一个的学生添加了一个条目档案。我当前的xsl代码(下面)似乎有效,但它在Student节点的底部添加了条目配置文件,而我想在<YRPRG>
之后添加它。这些文件在<PIDM>
和<NUMHUS>
上都匹配。我不认为这太难了,但我不熟悉XML,似乎无法使其发挥作用。有人可以帮忙解决这个问题吗?
文件1(XML):
<institution>
<student>
<PIDM>1</PIDM>
<NUMHUS>12</NUMHUS>
<YRPRG>1</YRPRG>
<Something>
<term>7</term>
<shortDescription>8</shortDescription>
</Something>
</student>
<student>
<PIDM>2</PIDM>
<NUMHUS>1</NUMHUS>
<YRPRG>2</YRPRG>
<something>
<term>70</term>
<shortDescription>80</shortDescription>
</something>
</student>
<student>
<PIDM>34</PIDM>
<NUMHUS>1</NUMHUS>
<YRPRG>1</YRPRG>
<Something>
<term>5</term>
<shortDescription>7</shortDescription>
</Something>
</student>
</institution>
文件2(XML):
<studentstoadd>
<entryprofile>
<PIDM>1</PIDM>
<NUMHUS>12</NUMHUS>
<PREVINST>1U40608</PREVINST>
<QUALENT3>1HUK</QUALENT3>
<WELBACC>1</WELBACC>
</entryprofile>
<entryprofile>
<PIDM>2</PIDM>
<NUMHUS>1</NUMHUS>
<PREVINST>2U40608</PREVINST>
<QUALENT3>2HUK</QUALENT3>
<WELBACC>2</WELBACC>
</entryprofile>
<entryprofile>
<PIDM>2</PIDM>
<NUMHUS>2</NUMHUS>
<DOMICILE>XK</DOMICILE>
<QUALENT3>3HUK</QUALENT3>
<WELBACC>3</WELBACC>
</entryprofile>
</studentstoadd>
所需的输出(XML):
<institution>
<student>
<PIDM>1</PIDM>
<NUMHUS>12</NUMHUS>
<YRPRG>1</YRPRG>
<entryprofile>
<PREVINST>1U40608</PREVINST>
<QUALENT3>1HUK</QUALENT3>
<WELBACC>1</WELBACC>
</entryprofile>
<Something>
<term>7</term>
<shortDescription>8</shortDescription>
</Something>
</student>
<student>
<PIDM>2</PIDM>
<NUMHUS>1</NUMHUS>
<YRPRG>2</YRPRG>
<entryprofile>
<PREVINST>2U40608</PREVINST>
<QUALENT3>2HUK</QUALENT3>
<WELBACC>2</WELBACC>
</entryprofile>
<something>
<term>70</term>
<shortDescription>80</shortDescription>
</something>
</student>
</institution>
我的样式表包含以下代码:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="student">
<xsl:copy>
<xsl:apply-templates/>
<xsl:copy-of select="document('s2.xml')//entryprofile[PIDM=current()/PIDM]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="student">
<xsl:copy>
<xsl:apply-templates/>
<xsl:copy-of select="document('s2.xml')//entryprofile[NUMHUS=current()/NUMHUS]"/>
</xsl:copy>
</xsl:template>
答案 0 :(得分:1)
如果要在YRPRG
之后插入节点,则应在匹配YRPRG
的模板中执行此操作 - 例如:
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="YRPRG">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<xsl:copy-of select="document('s2.xml')//entryprofile[PIDM=current()/../PIDM and NUMHUS=current()/../NUMHUS]"/>
</xsl:template>
</xsl:stylesheet>
注意:最好使用 key 查找其他文档中的匹配条目。确切的方法取决于您使用的是XSLT 1.0还是2.0(您没有回答我关于您的版本的问题)。
答案 1 :(得分:0)
我当前的xsl代码(如下所示)似乎有效但是它在学生节点的底部添加了条目配置文件,而我想在
之后添加它
改变这个:
<xsl:template match="student">
<xsl:copy>
<xsl:apply-templates/>
<xsl:copy-of select="document('s2.xml')//entryprofile[PIDM=current()/PIDM]"/>
</xsl:copy>
</xsl:template>
对此:
<xsl:template match="student">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
<xsl:copy-of select="document('s2.xml')//entryprofile[PIDM=current()/PIDM]"/>
</xsl:template>
会在 student
元素后添加,正如您在问题中提到的那样。这是有效的,因为xsl:copy
创建了一个浅的副本(即,只复制student
元素,但不复制其子元素)。以下xsl:apply-templates
应用其子项的模板(处理节点)。通过在xsl:copy-of
内添加xsl:copy
,您可以将其作为student
子项的一部分。通过将放在 xsl:copy
之后,将其设为兄弟节点。
(编辑)或更改为此,如果您的引用要求将其作为student
的第一个孩子:
<xsl:template match="student">
<xsl:copy>
<xsl:copy-of select="document('s2.xml')//entryprofile[PIDM=current()/PIDM]"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
注1:使用xsl:copy-of
,无法进一步处理您从s2.xml
文档中选择的节点(如果需要)。如果要修改其内容,可以将模板应用于它们。为防止将匹配模板与原始源文档混合,您可以使用模式。
注2:你有两个<xsl:template match="student">
,其中任何一个都没有xsl:next-match
,所以只有最后一个匹配(XSLT 2.0通常的行为,但可能依赖于在处理器上,XSLT 3.0依赖于xsl:mode
声明。如果您要为每个entryprofile
附加两个student
,请按以下方式添加:
<xsl:template match="student">
<xsl:variable name="entryprofiles" select="document('s2.xml')//entryprofile" />
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
<xsl:copy-of select="$entryprofiles[PIDM=current()/PIDM]"/>
<xsl:copy-of select="$entryprofiles[NUMHUS=current()/NUMHUS]"/>
</xsl:template>
注3:在你写的评论中写道:
文件在PIDM和NUMHUS上匹配,我想在YRPRG之后插入相关学生的参赛资料。
但我不知道&#34;相关学生&#34;手段。这似乎与您原始问题的问题不同,在这种情况下,我建议您提出一个新问题,指明您在哪里遇到麻烦。
来自你的评论:
谢谢亚伯。相关学生我只是意味着文件1中的PIDM和NUMHUS与文件2中的PIDM和NUMHUS组合相匹配的学生
显然,michael.hor257k在他的OP上发表了评论。你应该用钥匙解决这个问题。但是,由于我认为这是一个高级主题而你说你刚刚开始,所以没有键就可以做到这一点(一旦你开始学习键,你可以问一个不同的问题)。
<!-- globabl variable, remove local one -->
<xsl:variable name="entryprofiles" select="doc('s2.xml')/*/entryprofile" />
<!-- change your copy-of as follows -->
<xsl:copy-of select="$entryprofiles[PIDM=current()/PIDM][NUMHUS=current()/NUMHUS]"/>