Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml XSLT将多个源文档合并到组合节点中_Xml_Xslt - Fatal编程技术网

Xml XSLT将多个源文档合并到组合节点中

Xml XSLT将多个源文档合并到组合节点中,xml,xslt,Xml,Xslt,我正在尝试将两个或多个源文档的内容合并到一个输出文档中,其中内容应该位于相同的节点中 这两个源文档是Resources.resx: <?xml version="1.0" encoding="utf-8"?> <root> <data name="ButtonCancelString"> <value>Cancel</value> </data> <data name="ButtonCloseStr

我正在尝试将两个或多个源文档的内容合并到一个输出文档中,其中内容应该位于相同的节点中

这两个源文档是Resources.resx:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <data name="ButtonCancelString">
    <value>Cancel</value>
  </data>
  <data name="ButtonCloseString">
    <value>Close</value>
  </data>
</root>

取消
接近
和Resources.de.resx:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <data name="ButtonCancelString">
    <value>Abbrechen</value>
  </data>
  <data name="ButtonCloseString">
    <value>Schließen</value>
  </data>
</root>

取消
施利恩
我使用以下转换(combine.xslt):


我在空xml上运行转换:

<?xml version="1.0" encoding="UTF-8"?>
<empty/>

生成的文档如下所示(消除了一些噪音):


取消
接近
取消
施利恩
但我需要的不是重复节点,而是以下输出:

<?xml version="1.0" encoding="UTF-8"?>
<root >
    <constants>
        <const name="ButtonCancelString">
            <text lang="en">Cancel</text>
            <text lang="de">Abbrechen</text>
        </const>
        <const name="ButtonCloseString">
            <text lang="en">Close</text>
            <text lang="de">Schließen</text>
        </const>
    </constants>
</root>

取消
取消
接近
施利恩

有没有一种方法可以通过Transformations实现这一点?

由于您的样式表具有
version=“2.0”
我已经编写了一个XSLT 2.0解决方案,我会对每个组使用键或
,在下面的示例中,我使用了键。它需要
Resources.resx
作为主要输入文档,其他文档需要
Resource.lang.resx
格式字符串序列的参数:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"
  exclude-result-prefixes="xs fn">

    <xsl:param name="resource-urls" as="xs:string*" select="'Resources.de.resx', 'Resources.es.resx'"/>

    <xsl:variable name="resource-docs" as="document-node()*" select="for $url in $resource-urls return doc($url)"/>

    <xsl:key name="name" match="data" use="@name"/>

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/root">
        <root>
            <constants>
                <xsl:apply-templates select="data"/>
            </constants>
        </root>
    </xsl:template>

    <xsl:template match="/root/data">
        <const name="{@name}">
          <xsl:apply-templates select="., for $doc in $resource-docs return key('name', @name, $doc)" mode="value"/>
        </const>
    </xsl:template>

    <xsl:template match="/root/data" mode="value">
        <xsl:variable name="name-tokens" select="tokenize(tokenize(document-uri(/), '/')[last()], '\.')"/>
        <xsl:variable name="language" as="xs:string" select="if ($name-tokens[3]) then $name-tokens[2] else 'en'"/>
        <text lang="{$language}">
          <xsl:value-of select="value"/>
        </text>
    </xsl:template>
</xsl:stylesheet>

太棒了,我认为您不仅解决了我的问题,还设计了一个可以扩展到其他语言的解决方案。非常感谢你。
<?xml version="1.0" encoding="UTF-8"?>
<root >
    <constants>
        <const name="ButtonCancelString">
            <text lang="en">Cancel</text>
            <text lang="de">Abbrechen</text>
        </const>
        <const name="ButtonCloseString">
            <text lang="en">Close</text>
            <text lang="de">Schließen</text>
        </const>
    </constants>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"
  exclude-result-prefixes="xs fn">

    <xsl:param name="resource-urls" as="xs:string*" select="'Resources.de.resx', 'Resources.es.resx'"/>

    <xsl:variable name="resource-docs" as="document-node()*" select="for $url in $resource-urls return doc($url)"/>

    <xsl:key name="name" match="data" use="@name"/>

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/root">
        <root>
            <constants>
                <xsl:apply-templates select="data"/>
            </constants>
        </root>
    </xsl:template>

    <xsl:template match="/root/data">
        <const name="{@name}">
          <xsl:apply-templates select="., for $doc in $resource-docs return key('name', @name, $doc)" mode="value"/>
        </const>
    </xsl:template>

    <xsl:template match="/root/data" mode="value">
        <xsl:variable name="name-tokens" select="tokenize(tokenize(document-uri(/), '/')[last()], '\.')"/>
        <xsl:variable name="language" as="xs:string" select="if ($name-tokens[3]) then $name-tokens[2] else 'en'"/>
        <text lang="{$language}">
          <xsl:value-of select="value"/>
        </text>
    </xsl:template>
</xsl:stylesheet>