2012-08-06 96 views
2

我有一个主XML文档这样的:替换XML文件的属性值1.0

<chapter xmlns:xi="http://www.w3.org/2001/XInclude" xml:id="chapter1"> 
<title>First chapter</title> 
     <section xml:id="section1"> 
       <imageobject> 
        <id>aa12</id> 
        <image fileref="image1.jpg"/> 
       </imageobject> 
       <imageobject> 
        <id>bb13</id> 
        <image fileref="image2.jpg"/> 
       </imageobject> 
     </section> 
     <section xml:id="section2" xml:base="../other/section1.xml"> 
        <imageobject> 
         <id>ab14</id> 
         <image fileref="image1.jpg"/> 
        </imageobject> 
        <imageobject> 
         <id>ab15</id> 
         <image fileref="image2.jpg"/> 
        </imageobject> 

      <section xml:id="section3" xml:base="../some-other/more/section3.xml"> 
        <imageobject> 
         <id>ac16</id> 
         <image fileref="image1.jpg"/> 
        </imageobject> 
      </section> 
    </section> 
    <section xml:id="section4" xml:base="../some-other/section4.xml"> 
        <imageobject> 
         <id>ac17</id> 
         <image fileref="image2.jpg"/> 
        </imageobject> 
    </section> 
</chapter> 

和另一个XML文件和值等:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
    <NewData> 
     <Rename id="ab14" imageName="aaaa.jpg"/> 
     <Rename id="ab15" imageName="bbbb.jpg"/> 
     <Rename id="ac16" imageName="cccc.jpg"/> 
     <Rename id="ac17" imageName="dddd.jpg"/> 
    </NewData> 

而最后我需要一个类似下面的输出,根据id值将其替换为正确的重命名图像名称。

<chapter xmlns:xi="http://www.w3.org/2001/XInclude" xml:id="chapter1"> 
    <title>First chapter</title> 
    <section xml:id="section1"> 
        <imageobject> 
         <image fileref="image1.jpg"/> 
        </imageobject> 
        <imageobject> 
         <image fileref="image2.jpg"/> 
        </imageobject> 
    </section> 
    <section xml:id="section2" xml:base="../other/section1.xml"> 
         <imageobject> 
          <image fileref="aaaa.jpg"/> 
         </imageobject> 
         <imageobject> 
          <image fileref="bbbb.jpg"/> 
         </imageobject> 

      <section xml:id="section3" xml:base="../some-other/more/section3.xml"> 
         <imageobject> 
          <image fileref="cccc.jpg"/> 
         </imageobject> 
      </section> 
    </section> 
    <section xml:id="section4" xml:base="../some-other/section4.xml"> 
         <imageobject> 
          <image fileref="dddd.jpg"/> 
         </imageobject> 
    </section> 
</chapter> 

这里发生的是:如果第一个XML文档中的id属性从第二XML的id属性相匹配,那么fileref第一文档中的值由匹配imageName从第二XML文件替换。

请看我在这里给出的例子。

我该如何使用XSLT 1.0来做到这一点?

我正在使用Saxon或Xsltproc处理器。

在此先感谢..!

回答

3

下面是一个XSLT 1.0样式表(使用exsl:其由两个xsltproc的支持以及撒克逊6节点集):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:exsl="http://exslt.org/common" 
    exclude-result-prefixes="exsl"> 

<xsl:param name="doc2-url" select="'test2012080602.xml'"/> 
<xsl:variable name="doc2" select="document($doc2-url)"/> 

<xsl:strip-space elements="*"/> 
<xsl:output indent="yes"/> 

<xsl:key name="img-by-id" match="Rename" use="@id"/> 

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

<xsl:template match="imageobject"> 
    <xsl:copy> 
    <xsl:variable name="id" select="id"/> 
    <xsl:variable name="ref"> 
     <xsl:for-each select="$doc2"> 
     <xsl:if test="key('img-by-id', $id)"> 
      <image filref="{key('img-by-id', $id)/@imageName}"/> 
     </xsl:if> 
     </xsl:for-each> 
    </xsl:variable> 
    <xsl:variable name="new" select="exsl:node-set($ref)/image"/> 
    <xsl:choose> 
     <xsl:when test="$new"> 
     <xsl:copy-of select="$new"/> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:copy-of select="image"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

可以将参数doc2-url设置为二次输入的位置具有新名称的文件。

+0

Woow .. !! = D这非常好。非常感谢你Martin ..你真棒.. – vish 2012-08-06 11:08:20

+0

Martin,我看不到'ext:node-set()'在这里被使用 - 也许你需要编辑回答并删除提及EXSLT - 还有代码中的命名空间声明? – 2012-08-06 12:13:40

+0

Dimitre,我不明白你在评论中提出的问题。在样式表示例中,你看不见'我可以理解使用'exsl:node-set'是否有必要解决这个问题的想法,但是现在我想XSLT 2.0太多了,就像使用和访问XPath临时树那样如果可用,我更喜欢在XSLT 1.0中使用'exsl:node-set'。 – 2012-08-06 13:53:49