0

so i currently have a Document that has a bunch of XML inside of it. Like listed Below

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="datalog.xsl"?>
<ROOT>
<Vehicle>
    <ADGCode>44095650</ADGCode>
    <Brand>Mercedes Benz</Brand>
    <Model>ML 63 AMG (375 kW)</Model>
    <NewUsed>Used</NewUsed>
    <Year>2007</Year>
    <Mileage>166000</Mileage>
    <Price>289990</Price>
    <Colour>Black</Colour>
    <StockNo/>

    <Extras>Airbag - Driver, Pass &amp; Sides
    Air Conditioner
    ABS
    Central Locking Key
    Radio/CD
    Cruise Control
    Electric Mirrors
    Electric Windows - Front &amp; Back
    Heated Front Seats
    Multi-function Steering Wheel
    Navigation System
    Power Steering
    Sunroof - Electric
    Xenon Headlights
    </Extras>

</Vehicle>

And it Translates in XSL Like this

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

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
        <th>Image</th>
      <th>ADG Code</th>
      <th>Brand</th>
      <th>Model</th>
      <th>New / Used</th>
      <th>Year</th>
      <th>Mileage</th>
      <th>Price</th>
      <th>Colour</th>
    </tr>
    <xsl:for-each select="ROOT/Vehicle">
    <tr>
        <td>
        <img width="200px">
            <xsl:attribute name="src">
              <xsl:value-of select="Images/Image"/>
            </xsl:attribute>
        </img>
    </td>   
      <td><xsl:value-of select="ADGCode"/></td>
      <td><xsl:value-of select="Brand"/></td>
      <td><xsl:value-of select="Model"/></td>
      <td><xsl:value-of select="NewUsed"/></td>
      <td><xsl:value-of select="Year"/></td>
      <td><xsl:value-of select="Mileage"/></td>
      <td><xsl:value-of select="Price"/></td>
      <td><xsl:value-of select="Colour"/></td>
    </tr>
    <tr>
        <td colspan="9"><xsl:value-of select="Extras"/></td>
    </tr>
    <br />
    </xsl:for-each>
  </table>

  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

But what i want to know is how can i modify the XML document to read a link from a live XML sheet that is hosted on a website that the Supplier gives me to display their second hand cars from their database?

I am not sure if it is something as simple and instead of putting in the link on the XML document, or do I have to do something else? I could not find answers anywhere else on the web.

Your help and guidance would be greatly appreciated.

  • 1
    To answer your question, we would need to see an example of the other (hosted) XML document, and the expected (combined) output of the transformation. – michael.hor257k Jan 29 '15 at 07:11

1 Answers1

0

You can use xi:include to reference external xml content that must be included in your XML input:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="datalog.xsl"?>
<ROOT>
    <!-- external xml content -->
    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
        href="http://url.of.your/external/xml/content" parse="xml"/>
    <!-- your local xml content -->
    <Vehicle>
      <ADGCode>44095650</ADGCode>
      <Brand>Mercedes Benz</Brand>
      ...
    </Vehicle>
</ROOT>

Note that for this solution to work:

  • the & characters in the query string of the URL must be properly escaped using the &amp; entity, for the XML to be well formed
  • xi:include must be supported by your xslt processor (with Saxon you must use the -xi command line option)
  • you may need to adjust your xslt transformation

For example, if the external xml has the same structure of your local one (ROOT document element with Vehicle children) the composed xml will be like this:

<ROOT>
    <!-- external xml content -->
    <ROOT>
        <Vehicle>
            <ADGCode>65897159</ADGCode>
            ...
        </Vehicle>
    </ROOT>
    <!-- your local xml content -->
    <Vehicle>
      <ADGCode>44095650</ADGCode>
      <Brand>Mercedes Benz</Brand>
      ...
    </Vehicle>
</ROOT>

So your xsl:for-each loop should be:

<xsl:for-each select="//Vehicle">
    ...
</xsl:for-each>

in order to match Vehicle elements at any depth.

Edit:

A comment clarified that the question is about how to apply a local XSLT to a remote XML (I initially misunderstood that the input was local XML + remote XML).

So, this question is very similar to How to apply XSLT on XML with just XInclude, whose answer refers to the answer to a different question by the same user, Sean B. Durkin.

Using that approach, your input file is simply:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="transform.xsl"?>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
    href="http://www.carfind.co.za/xmlfeeds/pickup.aspx?feedid=352&amp;templatetype=DealershipWebsite&amp;accesskey=9A6A5A7C" 
    parse="xml"/>

and the XSLT needs to be slightly modified in order to match the xi:include element:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xi="http://www.w3.org/2001/XInclude"
  exclude-result-prefixes="xi">

<xsl:output method="html"/>

<xsl:template match="xi:include[@href][@parse='xml' or not(@parse)]">
  <xsl:apply-templates select="document(@href)" />
</xsl:template>

<xsl:template match="ROOT">
  <html>
      ...
      <xsl:for-each select="Vehicle">
          ...
      </xsl:for-each>
      ...
  </html>
</xsl:template>
</xsl:stylesheet>

Now, you can open your minimal XML file in the browser, and the result should be the expected one (it might depend on the browser; on my Mac, it works with Safari but not with Firefox, maybe because of security settings).

Community
  • 1
  • 1
lfurini
  • 3,729
  • 4
  • 30
  • 48
  • 1
    I did this, and i seem to be getting this error on my XML Feeds live URL. XML Parsing Error: not well-formed Location: file:///C:/Users/Media/Desktop/datalog.xml Line Number 5, Column 84: href="http://www.carfind.co.za/xmlfeeds/pickup.aspx?feedid=352&templatetype=DealershipWebsite&accesskey=9A6A5A7C" parse="xml"/> -----------------------------------------------------------------------------------^ The Up Arrow at the end of the breadcrumbs leads to the = Sign before Dealership. – user3274603 Feb 11 '15 at 12:40
  • 1
    The `&` characters in your URL must be replaced by `&` in order for the XML to be well formed: ` (I'm going to update the answer)` – lfurini Feb 11 '15 at 16:42
  • 1
    just to be clear I do not want any local content in there actually. but the structure is the same in the external one. so i added this but when i preview it nothing shows up? am i doing something seriously wrong here? thanks so much for your help! – user3274603 Feb 12 '15 at 18:51