将内容从一个xml拉到另一个xml

时间:2013-08-27 20:48:04

标签: xslt xslt-2.0

我有两个不同的xmls(唯一引用是@id)。当@id匹配时,需要将B.xml的“transunit / target”的所有子节点复制到A.xml的节点。请查看A.xml和B.xml。

注意:B.xml中的所有目标内容都是“Translated”

的后缀

XSLT 2.0版和处理器Saxon EE / HE 9.X.X.X

A.XML

<concept id="001" xml:lang="en-us">
    <title id="002">Notice</title>
    <shortdesc id="003">This information U.S.A.</shortdesc>
    <conbody id="004">
        <p id="005">This product blah blah <companyname id="006">blah bla</companyname> No other warranty expressed or implied. </p>
        <p id="007">This supersedes all previous notices.</p>
        <section id="008">
            <title id="009">COPYRIGHT LICENSE:</title>
            <p id="010">This information contains <b id="011">in source language</b> , blah blah</p>
        </section>
    </conbody>
</concept>

B.XML

<root>
    <transunit id="002">
        <source>Notice</source>
        <target>Translated:Notice</target>
    </transunit>
    <transunit id="003">
        <source>This information U.S.A.</source>
        <target>Translated:This information U.S.A.</target>
    </transunit>
    <transunit id="005">
        <source>This product blah blah <companyname id="006" local-name="companyname">blah bla</companyname> No other warranty expressed or implied. </source>
        <target>Translated:This product blah blah <companyname id="006" local-name="companyname">blah bla</companyname> No other warranty expressed or implied. </target>
    </transunit>
    <transunit id="007">
        <source>This supersedes all previous notices.</source>
        <target>Translated:This supersedes all previous notices.</target>
    </transunit>
    <transunit id="009">
        <source>COPYRIGHT LICENSE:</source>
        <target>Translated:COPYRIGHT LICENSE:</target>
    </transunit>
    <transunit id="010">
        <source>This information contains <b id="011" local-name="b">in source language</b> , blah blah</source>
        <target>Translated:This information contains <b id="011" local-name="b">in source language</b> , blah blah</target>
    </transunit>
</root>

预期结果:

<concept id="001" xml:lang="en-us">
    <title id="002">Translated:Notice</title>
    <shortdesc id="003">Translated:This information U.S.A.</shortdesc>
    <conbody id="004">
        <p id="005">Translated:This product blah blah <companyname id="006">blah bla</companyname> No other warranty expressed or implied. </p>
        <p id="007">Translated:This supersedes all previous notices.</p>
        <section id="008">
            <title id="009">Translated:COPYRIGHT LICENSE:</title>
            <p id="010">Translated:This information contains <b id="011">in source language</b> , blah blah</p>
        </section>
    </conbody>
</concept>

我正在尝试类似的事情:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:template match="node()">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>
<xsl:template match="*[count(ancestor::*) != 0]" priority="2">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:variable name="id">
            <xsl:value-of select="@id"/>
        </xsl:variable>
        <xsl:choose>
            <xsl:when test="document('B.xml')//*[$id=@id]">
            <xsl:for-each select="document('B.xml')//*[$id=@id]/target">
            <xsl:message>i m hre</xsl:message>
            <xsl:apply-templates/>
        </xsl:for-each>
    </xsl:when>
    <xsl:otherwise>
        <xsl:apply-templates/>
    </xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:1)

此XSLT 2.0样式表...

<xsl:stylesheet version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />
<xsl:param name="translations" select="''" />

<xsl:variable name="valid-ids" as="xs:string*">
 <xsl:if test="$translations ne ''">
  <xsl:sequence select="document($translations)//*[target]/@id" />
 </xsl:if>
</xsl:variable>

<xsl:key name="trans" match="*[@id][target]" use="@id" />

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

<xsl:template match="*[@id = $valid-ids]">
 <xsl:variable name="id" select="@id" />
 <xsl:copy>
  <xsl:apply-templates select="@*" />
  <xsl:for-each select="document($translations)">
   <xsl:apply-templates select="key('trans',$id)/target/node()" />
  </xsl:for-each>
 </xsl:copy> 
</xsl:template>

</xsl:stylesheet>

...使用命令行(对于Saxon处理器)...

"C:\Program Files\Saxonica\SaxonHE9.5N\bin\transform" "-s:A.xml" "-xsl:sheet.xsl" "-o:outp.xml" "translations=B.xml"

...使用两个给定的输入文件(A.xml是主输入文档,B.xml作为样式表参数引用,产生...

<concept id="001" xml:lang="en-us">
   <title id="002">Translated:Notice</title>
   <shortdesc id="003">Translated:This information U.S.A.</shortdesc>
   <conbody id="004">
      <p id="005">Translated:This product blah blah <companyname id="006" local-name="companyname">blah bla</companyname> No other warranty expressed or implied. </p>
      <p id="007">Translated:This supersedes all previous notices.</p>
      <section id="008">
         <title id="009">Translated:COPYRIGHT LICENSE:</title>
         <p id="010">Translated:This information contains <b id="011" local-name="b">in source language</b> , blah blah</p>
      </section>
   </conbody>
</concept>

注意

您可以通过添加doc-avail() function来增强此样式表的功能。选择如何处理指定但不可用的翻译文档。可以实施一些合理的选择。


感谢Martin,这是第二个模板的改进版本。

<xsl:template match="*[@id = $valid-ids]">
 <xsl:copy>
  <xsl:apply-templates select="@*,key('trans',@id, document($translations))/target/node()" />
 </xsl:copy> 
</xsl:template>