Как расширить этот XSLT для динамического включения полей XML? - PullRequest
1 голос
/ 09 марта 2009

Нам нужно проанализировать XML-файл с XSLT в CVS-файл. Код ниже работает , но только если поля в XML всегда постоянны.

Поля в нашем XML-файле всегда будут разными. Как я могу изменить свой XSLT-файл, чтобы он динамически включал в CSV-файл все поля из XML-файла?

XML:

<?xml version="1.0" encoding="iso-8859-1"?>
<data>
    <row>
        <customerID>06104539-463E-4B1A-231-34342343434</customerID>
        <contactID>23434-99F2-4325-B228-6F343483469389FB</contactID>
        <firstName>Jim</firstName>
        <lastName>Smith</lastName>
    </row>
    <row>
        <customerID>223434-463E-4B1A-231-A1E7EA248796</customerID>
        <contactID>6675767-99F2-4325-B234328-6F83469389FB</contactID>
        <specialID>112332</specialID>
        <firstName>John</firstName>
        <middleName>S.</middleName>
        <lastName>Jones</lastName>
    </row>
</data>

XSLT:

<?xml version="1.0" encoding="ISO-8859-1"?>

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

<xsl:template match="/">
    customerID,contactID<br/>
    <xsl:for-each select="data/row">
        <xsl:value-of select="customerID"/>,<xsl:value-of select="contactID"/><br/>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Вот файл ASP.NET, который анализирует файлы выше:

<%@ Page Language="c#" %>
<%@ import Namespace="System.Xml" %>
<%@ import Namespace="System.Xml.Xsl" %>
<%@ import Namespace="System.Xml.XPath" %>
<%@ import Namespace="System.IO" %>
<%@ import Namespace="System.Text" %>
<script runat="server">

    public void Page_Load(Object sender, EventArgs E) {

        string xmlPath = Server.MapPath("test2.xml");
        string xslPath = Server.MapPath("test2.xsl");

        StreamReader reader = null;;
        XmlTextReader xmlReader = null;

        FileStream fs = new FileStream(xmlPath, FileMode.Open, FileAccess.Read);
        reader = new StreamReader(fs,Encoding.UTF7);
        xmlReader = new XmlTextReader(reader);
        XPathDocument doc = new XPathDocument(xmlReader);

        XslTransform xslDoc = new XslTransform();
        xslDoc.Load(xslPath);

        xslDoc.Transform(doc,null, Response.Output);

        reader.Close();
        xmlReader.Close();

    }

</script>

Ответы [ 3 ]

3 голосов
/ 09 марта 2009

Я вспомнил, как делал что-то похожее в прошлом, и просматривал мою архивную работу, вот так:

<?xml version="1.0" encoding="ISO-8859-1"?>

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

    <xsl:key name="muench" match="/data/row/*" use="local-name()"/>

    <xsl:template match="/">
        <xsl:for-each select="/data/row/*[generate-id() = generate-id(key('muench',local-name())[1])]">
            <xsl:if test="not(position()=1)">,</xsl:if><xsl:value-of select="local-name()"/>
        </xsl:for-each>
        <br/>
        <xsl:for-each select="/data/row">
            <xsl:variable name="current" select="."/>
            <xsl:for-each select="/data/row/*[generate-id() = generate-id(key('muench',local-name())[1])]">
                <xsl:variable name="field" select="local-name()"/>
                <xsl:if test="not(position()=1)">,</xsl:if><xsl:value-of select="$current/*[local-name()=$field]"/>             
            </xsl:for-each>
            <br/>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

Все приветствуют уродливых, но функциональных.

Я серьезно не горжусь этим, но я обновил ваши данные и проверил, и это работает.

1 голос
/ 09 марта 2009

Разве другой цикл для каждого не сделает работу за вас?

<?xml version="1.0" encoding="ISO-8859-1"?>  
  <xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
    <xsl:template match="/">  
      customerID,contactID<br/>  
      <xsl:for-each select="data/row">  
        <xsl:for-each select="*">  
          <xsl:value-of select="."/>,  
        </xsl:for-each>  
        <br/>      
      </xsl:for-each>  
   </xsl:template>  
</xsl:stylesheet>  

С уважением,

Aaron

0 голосов
/ 09 марта 2009

Проблема здесь в том, что первая «строка» может содержать 3 элемента, а остальные строки - 5 элементов. Так что будет сложно извлечь заголовок.

Для сортировки используйте xsl: sort

Для подсчета используйте функцию xslt count ()

Сортировка по количеству элементов, получение заголовка, создание коллекции элементов в заголовке, а затем для каждой строки отсканируйте его для этих элементов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...