dougao2830
2014-06-04 03:09
浏览 57

使用XSL从URL合并2 XML

i'm working with an API that gives me two URLs to pull the content from.

The first one gives me a list of products but with limited information about each.

The second url, by using ?productId=1 i can pull the rest of the data about a specific product.

What i'm trying to do is to merge these two things into one, so i could easily import to a wordpress or somewhere else later on.

I've tried doing it with DOM+PHP and i couldn't get it to work, perhaps the xsl would be the better solution?

File1.svc

<products>
  <product>
    <product_id> 1 </product_id>
    <product_name> Product 1 </product_name>
  </product>
  <product>
    <product_id> 2 </product_id>
    <product_name> Product 2 </product_name>
  </product>
</products>

File2.svc?productId=1

<results>
  <product product_id="1">
    <price_from> 100 </price_from>
    <price_to> 300 </price_to>
  </product>
</results>

Result i want to export:

<products>
  <product>
    <product_id> 1 </product_id>
    <product_name> Product 1 </product_name>
    <price_from> 100 </price_from>
    <price_to> 300 </price_to>
  </product>
  <product>
    <product_id> 2 </product_id>
    <product_name> Product 2 </product_name>
    <price_from> 400 </price_from>
    <price_to> 500 </price_to>
  </product>
</products>

图片转代码服务由CSDN问答提供 功能建议

我正在使用一个API,它提供了两个从中提取内容的URL。

第一个给我一个产品列表,但每个产品的信息有限。

第二个网址,使用?productId = 1我可以提取剩余的数据 关于特定产品。

我想要做的是将这两个东西合并为一个,这样我就可以轻松导入wordpress或其他地方了。

我尝试过使用DOM + PHP,我无法让它工作,也许xsl会是更好的解决方案吗?

File1.svc

 &lt; products&gt; 
&lt; product&gt; 
&lt; product_id&gt;  1&lt; / product_id&gt; 
&lt; product_name&gt; 产品1&lt; / product_name&gt; 
&lt; / product&gt; 
&lt; product&gt; 
&lt; product_id&gt;  2&lt; / product_id&gt; 
&lt; product_name&gt; 产品2&lt; / product_name&gt; 
&lt; / product&gt; 
&lt; / products&gt; 
   
 
 

File2.svc?productId = 1

 &lt; results&gt; 
&lt; product product_id =“1”&gt; 
&lt; price_from&gt;  100&lt; / price_from&gt; 
&lt; price_to&gt;  300&lt; / price_to&gt; 
&lt; / product&gt; 
&lt; / results&gt; 
   
 
 

我要导出的结果: < / p>

 &lt; products&gt; 
&lt; product&gt; 
&lt; product_id&gt;  1&lt; / product_id&gt; 
&lt; product_name&gt; 产品1&lt; / product_name&gt; 
&lt; price_from&gt;  100&lt; / price_from&gt; 
&lt; price_to&gt;  300&lt; / price_to&gt; 
&lt; / product&gt; 
&lt; product&gt; 
&lt; product_id&gt;  2&lt; / product_id&gt; 
&lt; product_name&gt; 产品2&lt; / product_name&gt; 
&lt; price_from&gt;  400&lt; / price_from&gt; 
&lt; price_to&gt;  500&lt; / price_to&gt; 
&lt; / product&gt; 
&lt; / products&gt; 
   
 
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • dongshan3759 2014-06-04 03:52
    已采纳

    It should work well:

    #File1.svc
    $xml_A = <<<XML
    <products>
        <product>
            <product_id> 1 </product_id>
            <product_name> Product 1 </product_name>
        </product>  
    </products>
    XML;
    
    #File2.svc?productId=1
    $xml_B = <<<XML
    <results>
        <product product_id="1">
            <price_from> 100 </price_from>
            <price_to> 300 </price_to>
        </product>
    </results>
    XML;
    
    $a = new SimpleXMLElement($xml_A); //or new SimpleXMLElement($URL, null, true);
    $b = new SimpleXMLElement($xml_B); //or new SimpleXMLElement($URL, null, true);
    
    $priceFromElement = $b->product[0]->price_from;
    $priceToElement   = $b->product[0]->price_to;
    
    $a->product[0]->addChild($priceFromElement->getName(), $priceFromElement);
    $a->product[0]->addChild($priceToElement->getName(), $priceToElement);
    
    echo $a->asXML(); //merged
    
    已采纳该答案
    打赏 评论
  • dqkxo44488 2014-06-04 03:57

    Alternatively, you could parse them, build them on an array, then create another one. Consider this example:

    // if you want rough and gun processing
    $data = array();
    // sample values
    @$raw_xml1 = simplexml_load_string('<products> <product> <product_id> 1 </product_id> <product_name> Product 1 </product_name> </product> <product> <product_id> 2 </product_id> <product_name> Product 2 </product_name> </product></products>');
    @$raw_xml2 = simplexml_load_string('<results> <product product_id="1"> <price_from> 100 </price_from> <price_to> 300 </price_to> </product> <product product_id="2"> <price_from>400</price_from> <price_to>500</price_to> </product></results>');
    
    // the extraction
    foreach($raw_xml1->product as $key => $value) {
        $product_id = trim((string) $value->product_id);
        $data[$product_id] = array(
            'product_id' => $product_id,
            'product_name' => trim((string) $value->product_name),
        );
    }
    
    foreach($raw_xml2->product as $key => $value) {
        $product_id = trim((string) $value->attributes()['product_id']);
        $data[$product_id]['price_from'] = trim((string) $value->price_from);
        $data[$product_id]['price_to'] = trim((string) $value->price_to);
    }
    
    $final_xml = '<?xml version="1.0" encoding="UTF-8"?>';
    $final_xml .= '<products>';
    foreach($data as $key => $value) {
        $final_xml .= '<product>';
        foreach($value as $index => $element) {
            $final_xml .= "<$index>$element</$index>";
        }
        $final_xml .= '</product>';
    }
    $final_xml .= '</products>';
    
    // save it
    $xml = new SimpleXMLElement($final_xml);
    $xml->asXML('text.xml');
    // saved as xml file, should be saved on the same level as this php
    
    打赏 评论
  • dongwu9063 2014-06-04 04:25

    Here is a XSLT solution which selects the file according to the ID attached to the filename:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:output indent="yes"/>
    
        <xsl:template match="products">
            <copy>
                <xsl:apply-templates/>
            </copy>
        </xsl:template>
    
        <xsl:template match="product">
            <xsl:copy>
                <xsl:copy-of select="product_id"/>
                <xsl:copy-of select="product_name"/>
                <xsl:variable name="filepath" select="concat('File2.svc?productId=',normalize-space(product_id))"/>
                <xsl:copy-of select="document($filepath)/results/product/*"/>
            </xsl:copy>
        </xsl:template>
    
    </xsl:stylesheet>
    

    It could also check if the ID attribute is correct, but I assumed that checking ?productId= was enough since it filters the results by the ID as you said.

    打赏 评论

相关推荐 更多相似问题