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
XSLT-根据匹配的节点值从其他XML文件复制节点_Xml_Xslt_Transformation - Fatal编程技术网

XSLT-根据匹配的节点值从其他XML文件复制节点

XSLT-根据匹配的节点值从其他XML文件复制节点,xml,xslt,transformation,Xml,Xslt,Transformation,您好,我有两个不同的xml,我想根据匹配的源和目标xml节点值,从目标xml复制一个节点来合并它们 第一个xml是这样的: <PRODUCTS> <PRODUCT> <NAME>PRODUCT 1</NAME> <MAINCATID>38</MAINCATID> <SUBCATID>39</SUBCATID> </PRODUCT> </PRODUCTS

您好,我有两个不同的xml,我想根据匹配的源和目标xml节点值,从目标xml复制一个节点来合并它们

第一个xml是这样的:

<PRODUCTS>
  <PRODUCT>
    <NAME>PRODUCT 1</NAME>
    <MAINCATID>38</MAINCATID>
    <SUBCATID>39</SUBCATID>
  </PRODUCT>
</PRODUCTS>

产品1
38
39
第二个XML是这样的

 <CATEGORIES>
  <MAINCATEGORY>
   <MAINCATID>38</MAINCATID>
   <MAINCATNAME>CATEGORY 1</MAINCATNAME>
  </MAINCATEGORY>
  <MAINCATEGORY>
   <MAINCATID>37</MAINCATID>
   <MAINCATNAME>CATEGORY 2</MAINCATNAME>
  </MAINCATEGORY>
  <SUBCATEGORY>
   <SUBCATID>39</SUBCATID>
   <SUBCATNAME>SUB CATEGORY 1</SUBCATNAME>
  </SUBCATEGORY>
  <SUBCATEGORY>
   <SUBCATID>40</SUBCATID>
   <SUBCATNAME>SUB CATEGORY 2</SUBCATNAME>
  </SUBCATEGORY>
</CATEGORIES>

38
第一类
37
第2类
39
第1小类
40
次级类别2
我的xml结果应该是

<PRODUCTS>
  <PRODUCT>
    <NAME>PRODUCT 1</NAME>
    <MAINCATID>38</MAINCATID>
    <MAINCATNAME>CATEGORY 1</MAINCATNAME>
    <SUBCATID>39</SUBCATID>
    <SUBCATNAME>SUB CATEGORY 1</SUBCATNAME>
  </PRODUCT>
</PRODUCTS>

产品1
38
第一类
39
第1小类
有许多这样的节点。我想根据主目录ID和子目录ID从第二个xml中获取类别名称


您能帮我介绍一下XSLT转换吗

在XSLT中使用多个XML文档的关键是
document()
,下面是一个快速而肮脏的示例,演示了在处理
产品.XML
模板时引入
categories.XML
(根据@michael.hor257k的评论和一些调整进行编辑):


在XSLT1.0中,使用查找另一个文档中的数据有点笨拙,但无论从性能还是代码清晰度来看,它仍然是最好的方法IMHO。尝试:

XSLT1.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="*"/>

<xsl:variable name="lookup-source" select="document('file2.xml')" />

<xsl:key name="MAINCATID" match="MAINCATNAME" use="../MAINCATID" />
<xsl:key name="SUBCATID" match="SUBCATNAME" use="../SUBCATID" />

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

<xsl:template match="MAINCATID | SUBCATID">
    <xsl:copy-of select="."/>
    <xsl:variable name="key-name" select="local-name()"/>
    <xsl:variable name="key-value" select="."/>
    <!-- switch context to the other file for the actual lookup -->
    <xsl:for-each select="$lookup-source">
        <xsl:copy-of select="key($key-name, $key-value)" />
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>


这里我们假设您的“第一个xml”文档就是正在处理的文档

您是否尝试过
文档()
?我将尝试制作一个示例。您使用的是XSLT 1.0还是2.0?实际上,关键是使用一个键。-另外,您应该了解模板。@michael.hor257k感谢链接:它确实改进了我的示例。不过,我认为在一个XSL中使用多个XML的关键是
document()
我添加了一个答案来澄清我的意思。这个答案比我的好得多!谢谢。这个和饼干314的答案都对我有用。非常感谢
<PRODUCTS>
  <PRODUCT>
    <NAME>PRODUCT 1</NAME>
    <MAINCATID>38</MAINCATID>
    <MAINCATNAME>CATEGORY 1</MAINCATNAME>
    <SUBCATID>39</SUBCATID>
    <SUBCATNAME>SUB CATEGORY 1</SUBCATNAME>
  </PRODUCT>
<PRODUCTS>
<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="*"/>

<xsl:variable name="lookup-source" select="document('file2.xml')" />

<xsl:key name="MAINCATID" match="MAINCATNAME" use="../MAINCATID" />
<xsl:key name="SUBCATID" match="SUBCATNAME" use="../SUBCATID" />

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

<xsl:template match="MAINCATID | SUBCATID">
    <xsl:copy-of select="."/>
    <xsl:variable name="key-name" select="local-name()"/>
    <xsl:variable name="key-value" select="."/>
    <!-- switch context to the other file for the actual lookup -->
    <xsl:for-each select="$lookup-source">
        <xsl:copy-of select="key($key-name, $key-value)" />
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>