XSLT:从多个文件中收集和合并信息

时间:2016-04-06 07:52:28

标签: xml xslt

我尝试从多个xml文件中收集信息,并使用xslt将此信息合并到一个唯一的xml文件中

这是我原来的XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<objects>
    <object>
        <class>Class1</class>
        <attribute name="name" value="object1"/>
        <attribute name="id" value="1"/>
    </object>
    <object>
        <class>Class1</class>
        <attribute name="name" value="object2"/>
        <attribute name="id" value="2"/>
    </object>
    <object>
        <class>Class2</class>
        <attribute name="name" value="object3"/>
        <attribute name="id" value="3"/>
    </object>
</objects>

我有第二个xml文件(res.xml):

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <lang id="1">localizedObject1</lang>
</resources>

我有第三个xml文件(res2.xml):

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <lang id="1">localizedObjectDesc1</lang>
</resources>

这是我想得到的结果:

<?xml version="1.0" encoding="UTF-8"?>
<objects>
    <object>
        <class>Class1</class>
        <attribute name="name" value="object1"/>
        <attribute name="id" value="1"/>
        <attribute name="localizedValue" value="localizedObject1"/>
        <attribute name="localizedDescription" value="localizedObjectDesc1"/>
    </object>
    <object>
        <class>Class1</class>
        <attribute name="name" value="object2"/>
        <attribute name="id" value="2"/>
    </object>
    <object>
        <class>Class2</class>
        <attribute name="name" value="object3"/>
        <attribute name="id" value="3"/>
    </object>
</objects>

对于class = Class1且id在res.xml =&gt;中的所有对象添加属性(localizedValue)。如果id在res2.xml =&gt;中添加属性localizedDescription 对于所有其他对象=&gt;只需复制节点

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

可能有更简单的方法,但这在您的情况下效果很好:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:variable name="idXML" select="document('a2.xml')/resources" />

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

<xsl:template match="object">
  <xsl:copy>
    <xsl:apply-templates select="node()|@*" /> 
    <xsl:variable name="curValue" select="attribute[@name='id']/@value" />   
    <xsl:if test="class = 'Class1' and $idXML/lang[@id = $curValue]">
      <attribute name="localizedValue" value="{$idXML/lang[@id = $curValue]/text()}"/>
    </xsl:if>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

输出符合要求。您还可以在开头添加更多文档作为变量,并以相同的方式访问它们($idXML/...)。

答案 1 :(得分:0)

假设您可以使用XSLT 2.0处理器,则可以定义密钥

<xsl:key name="ref" match="resources/lang" use="@id"/>

然后按如下方式使用它:

<xsl:variable name="res-doc" select="document('res.xml')"/>
<xsl:variable name="res-doc2" select="document('res2.xml')"/>


<xsl:template match="object[class = 'Class1']/attribute[name = 'id']">
  <xsl:copy-of select="."/>
  <xsl:apply-templates select="key('ref', value, $res-doc)"/>
  <xsl:apply-templates select="key('ref', value, $res-doc2)" mode="desc"/>
</xsl:template>

<xsl:template match="resources/lang">
  <attribute name="localizedValue" value="{.}"/>
</xsl:template>

<xsl:template match="resources/lang" mode="desc">
  <attribute name="localizedDescription" value="{.}"/>
</xsl:template>

当然,请确保包含身份转换模板以复制其余模板:

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