基于一定条件的xml数据到xsl文件的转换

Posted

技术标签:

【中文标题】基于一定条件的xml数据到xsl文件的转换【英文标题】:Conversion of xml data to xsl file based on certain conditions 【发布时间】:2022-01-06 20:18:23 【问题描述】:

我正在尝试创建一个 xsl 文件,其中包含 xml 文件中的数据。 预期的输出应该只有从亚利桑那、佛罗里达和纽约拖曳的车辆的状态(xml文件在输出中有状态代码,它需要是输出示例中的状态的全名(佛罗里达州->佛罗里达州)。 链接到颜色代码(https://www.sarasotataxcollector.com/dealers/color-codes),它应该是 xml 输出中的缩写,它只是颜色代码。 必须首先列出最近拖曳的车辆。 我一直坚持,直到我能够取得进展,我被困在以下场景中。

    输出结构和相应的命名结构。 我不确定缩写在 XSl 中如何用于状态名称和颜色代码以获得以下输出。 我是 xsl 的初学者,xml 附加了我到目前为止所尝试的内容。 如果有人能指导我如何解决问题陈述,我将不胜感激。这是第一次接触堆栈溢出社区。 :) 预期输出应如下所示,这是一个示例,但对于我的 xml 数据,它应该与以下结构相同。

    <?xml version="1.0" encoding="UTF-8"?>
<summary>
    <state name="Indiana">
        <vehicle date="2020-02-27" plate="AE78117" color="White"/>
        <vehicle date="2020-02-27" plate="AJ6869" color="White"/>
        <vehicle date="2020-02-24" plate="305VWS" color="Red"/>
    </state>
    <state name="Florida">
        <vehicle date="2020-02-27" plate="2879YS" color="Aluminum"/>
        <vehicle date="2020-02-24" plate="KQRK15" color="Burgundy"/>
        <vehicle date="2020-02-22" plate="DFHW62" color="White"/>
        <vehicle date="2020-02-18" plate="JJZU83" color="White"/>

    </state>
    <state name="California">
        <vehicle date="2020-02-26" plate="JGC22988" color="Black"/>
        <vehicle date="2020-02-20" plate="JHK5166" color="Gray"/>
        <vehicle date="2020-02-13" plate="HKJ8739" color="Aluminum"/>
        <vehicle date="2020-02-07" plate="FMA1068" color="Red"/>
    </state>
</summary>

具有数据 Cars.xml 的 XML 文件

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="Towing.xsl"?>
<response>
    <tow>
        <tow_date>2021-09-27</tow_date>
        <make>BMW</make>
        <style>4D</style>
        <color>GRY</color>
        <state>CA</state>
        <towed_to_address>10300 S. Doty</towed_to_address>
        <tow_facility_phone>(773) 568-8495</tow_facility_phone>
        <inventory_number>2921620</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-11-12</tow_date>
        <make>NISS</make>
        <style>LL</style>
        <color>BLK</color>
        <plate>JJA5163</plate>
        <state>NY</state>
        <towed_to_address>701 N. Sacramento</towed_to_address>
        <tow_facility_phone>(773) 265-7605</tow_facility_phone>
        <inventory_number>7016434</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-09-02</tow_date>
        <make>CHEV</make>
        <style>LL</style>
        <color>GRY</color>
        <plate>BRB257</plate>
        <state>IN</state>
        <towed_to_address>10300 S. Doty</towed_to_address>
        <tow_facility_phone>(773) 568-8495</tow_facility_phone>
        <inventory_number>2920773</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-11-03</tow_date>
        <make>NISS</make>
        <style>VN</style>
        <color>BLU</color>
        <plate>FBY402</plate>
        <state>IN</state>
        <towed_to_address>701 N. Sacramento</towed_to_address>
        <tow_facility_phone>(773) 265-1846</tow_facility_phone>
        <inventory_number>1542941</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-10-10</tow_date>
        <make>CHRI</make>
        <style>4D</style>
        <color>WHI</color>
        <plate>549XIB</plate>
        <state>AZ</state>
        <towed_to_address>10300 S. Doty</towed_to_address>
        <tow_facility_phone>(773) 568-8495</tow_facility_phone>
        <inventory_number>2922125</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-11-07</tow_date>
        <make>CHEV</make>
        <style>4D</style>
        <color>BLU</color>
        <plate>282DLC</plate>
        <state>IN</state>
        <towed_to_address>701 N. Sacramento</towed_to_address>
        <tow_facility_phone>(773) 265-7605</tow_facility_phone>
        <inventory_number>7016277</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-10-23</tow_date>
        <make>CHEV</make>
        <style>VN</style>
        <color>WHI</color>
        <plate>AL33956</plate>
        <state>AZ</state>
        <towed_to_address>10300 S. Doty</towed_to_address>
        <tow_facility_phone>(773) 568-8495</tow_facility_phone>
        <inventory_number>2922721</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-11-11</tow_date>
        <make>FORD</make>
        <style>VN</style>
        <color>WHI</color>
        <plate>AJ82932</plate>
        <state>AZ</state>
        <towed_to_address>10300 S. Doty</towed_to_address>
        <tow_facility_phone>(773) 568-8495</tow_facility_phone>
        <inventory_number>2923515</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-09-21</tow_date>
        <make>NISS</make>
        <style>LL</style>
        <color>BLK</color>
        <plate>ZZ90397</plate>
        <state>IL</state>
        <towed_to_address>400 E. Lower Wacker</towed_to_address>
        <tow_facility_phone>(312) 744-7550</tow_facility_phone>
        <inventory_number>0245476</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-08-21</tow_date>
        <make>LEXS</make>
        <style>4D</style>
        <color>GRY</color>
        <plate>58AETN</plate>
        <state>FL</state>
        <towed_to_address>701 N. Sacramento</towed_to_address>
        <tow_facility_phone>(773) 265-7605</tow_facility_phone>
        <inventory_number>7011627</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-10-30</tow_date>
        <make>HOND</make>
        <style>4D</style>
        <color>BLK</color>
        <plate>8PED621</plate>
        <state>CA</state>
        <towed_to_address>400 E. Lower Wacker</towed_to_address>
        <tow_facility_phone>(312) 744-7550</tow_facility_phone>
        <inventory_number>0247537</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-11-07</tow_date>
        <make>HYUN</make>
        <style>4D</style>
        <color>RED</color>
        <plate>KNA3803</plate>
        <state>NY</state>
        <towed_to_address>701 N. Sacramento</towed_to_address>
        <tow_facility_phone>(773) 265-7605</tow_facility_phone>
        <inventory_number>7016231</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-11-07</tow_date>
        <make>CHEV</make>
        <style>4D</style>
        <color>GRY</color>
        <plate>HN8118</plate>
        <state>IN</state>
        <towed_to_address>701 N. Sacramento</towed_to_address>
        <tow_facility_phone>(773) 265-7605</tow_facility_phone>
        <inventory_number>7016177</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-08-22</tow_date>
        <make>HOND</make>
        <style>LL</style>
        <color>BLK</color>
        <plate>QTJF49</plate>
        <state>FL</state>
        <towed_to_address>701 N. Sacramento</towed_to_address>
        <tow_facility_phone>(773) 265-7605</tow_facility_phone>
        <inventory_number>7011737</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-11-11</tow_date>
        <make>CHEV</make>
        <style>LL</style>
        <color>WHI</color>
        <plate>AS16111</plate>
        <state>IL</state>
        <towed_to_address>10300 S. Doty</towed_to_address>
        <tow_facility_phone>(773) 568-8495</tow_facility_phone>
        <inventory_number>2923484</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-11-11</tow_date>
        <make>NISS</make>
        <style>4D</style>
        <color>TAN</color>
        <plate>Q286702</plate>
        <state>IL</state>
        <towed_to_address>10300 S. Doty</towed_to_address>
        <tow_facility_phone>(773) 568-8495</tow_facility_phone>
        <inventory_number>2923487</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-09-18</tow_date>
        <make>CHEV</make>
        <style>4D</style>
        <color>GRY</color>
        <plate>QGBU61</plate>
        <state>FL</state>
        <towed_to_address>400 E. Lower Wacker</towed_to_address>
        <tow_facility_phone>(312) 744-7550</tow_facility_phone>
        <inventory_number>0245317</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-10-30</tow_date>
        <make>DODG</make>
        <style>4D</style>
        <color>BLK</color>
        <plate>8UXV304</plate>
        <state>CA</state>
        <towed_to_address>10300 S. Doty</towed_to_address>
        <tow_facility_phone>(773) 568-8495</tow_facility_phone>
        <inventory_number>2922994</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-10-25</tow_date>
        <make>FORD</make>
        <style>LL</style>
        <model>TK</model>
        <color>WHI</color>
        <plate>NYVX68</plate>
        <state>FL</state>
        <towed_to_address>701 N. Sacramento</towed_to_address>
        <tow_facility_phone>(773) 265-7605</tow_facility_phone>
        <inventory_number>7015485</inventory_number>
    </tow>
    <tow>
        <tow_date>2021-10-11</tow_date>
        <make>JEEP</make>
        <style>LL</style>
        <color>WHI</color>
        <plate>8TIN875</plate>
        <state>CA</state>
        <towed_to_address>10300 S. Doty</towed_to_address>
        <tow_facility_phone>(773) 568-8495</tow_facility_phone>
        <inventory_number>2922224</inventory_number>
    </tow>
</response>

Towing.xsl 这是我尝试过的任何建议以使其更好。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="xml" encoding="UTF-8" indent="yes" />
   <xsl:template match="/">
      <xsl:element name="state">
         <xsl:for-each select="response/tow[state='AZ']">
         <xsl:sort select="tow_date" order="descending" />
            <state name ="AZ">
               <xsl:element name = "vehicle">
               <xsl:value-of select="tow_date" />
                  ,
               <xsl:value-of select="plate" />
                 ,
               <xsl:value-of select="color" />
            </xsl:element>
            </state>
         </xsl:for-each>
         <xsl:for-each select="response/tow[state='FL']">
            <state name="FL">
               <xsl:value-of select="tow_date" />
               ,
               <xsl:value-of select="plate" />
               ,
               <xsl:value-of select="color" />
            </state>
         </xsl:for-each>
         <xsl:for-each select="response/tow[state='NY']">
            <state name="NY">
               <xsl:value-of select="tow_date" />
               ,
               <xsl:value-of select="plate" />
               ,
               <xsl:value-of select="color" />
            </state>
         </xsl:for-each>
      </xsl:element>
   </xsl:template>
</xsl:stylesheet>

【问题讨论】:

您是否仅限于 XSLT 1.0? 是的,目前正在使用 1.0 你是同班同学吗:" ***.com/questions/70178476/… 【参考方案1】:

首先,你不想写三遍相同的代码,所以使用一个模板来处理来自所有三个状态的拖链:

XSLT 1.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:key name="tow-by-state" match="tow" use="state" />

<xsl:template match="/response">
    <summary>
        <state name="Arizona">
            <xsl:apply-templates select="key('tow-by-state', 'AZ')">
                <xsl:sort select="tow_date" data-type="text" order="descending"/>
            </xsl:apply-templates>
        </state>
        <state name="Florida">
            <xsl:apply-templates select="key('tow-by-state', 'FL')">
                <xsl:sort select="tow_date" data-type="text" order="descending"/>
            </xsl:apply-templates>
        </state>
        <state name="New York">
            <xsl:apply-templates select="key('tow-by-state', 'NY')">
                <xsl:sort select="tow_date" data-type="text" order="descending"/>
            </xsl:apply-templates>
        </state>
    </summary>
</xsl:template>

<xsl:template match="tow">
    <vehicle date="tow_date" plate="plate" color="color"/>
</xsl:template>

</xsl:stylesheet>

现在出现了通过颜色代码查找颜色的问题。这也可能相当简单,除了您的参考说明可以有 两个 颜色代码 - 这使得它有点复杂,尤其是。如果您仅限于 XSLT 1.0:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:codes="https://www.sarasotataxcollector.com/dealers/color-codes"
exclude-result-prefixes="codes">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="tow-by-state" match="tow" use="state" />

<xsl:template match="/response">
    <summary>
        <state name="Arizona">
            <xsl:apply-templates select="key('tow-by-state', 'AZ')">
                <xsl:sort select="tow_date" data-type="text" order="descending"/>
            </xsl:apply-templates>
        </state>
        <state name="Florida">
            <xsl:apply-templates select="key('tow-by-state', 'FL')">
                <xsl:sort select="tow_date" data-type="text" order="descending"/>
            </xsl:apply-templates>
        </state>
        <state name="New York">
            <xsl:apply-templates select="key('tow-by-state', 'NY')">
                <xsl:sort select="tow_date" data-type="text" order="descending"/>
            </xsl:apply-templates>
        </state>
    </summary>
</xsl:template>

<xsl:template match="tow">
    <vehicle date="tow_date" plate="plate">
        <xsl:attribute name="color">
            <xsl:variable name="colors" select="document('')/xsl:stylesheet/codes:colors/color" />
            <xsl:choose>
                <xsl:when test="contains(color, '/')">
                    <xsl:variable name="code1" select="substring-before(color, '/')" />
                    <xsl:variable name="code2" select="substring-after(color, '/')" />
                    <xsl:value-of select="$colors[@code=$code1]"/>
                    <xsl:text>/</xsl:text>
                    <xsl:value-of select="$colors[@code=$code2]"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$colors[@code=current()/color]"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:attribute>
    </vehicle>
</xsl:template>

<codes:colors>
    <color code="SIL">Aluminum</color>
    <color code="AME">Amethyst</color>
    <color code="BGE">Beige</color>
    <color code="BLK">Black</color>
    <color code="BLU">Blue</color>
    <color code="DBL">Blue (Dark)</color>
    <color code="LBL">Blue (Light)</color>
    <color code="BRZ">Bronze</color>
    <color code="BRN">Brown</color>
    <color code="MAR">Burgundy</color>
    <color code="CAM">Camouflage</color>
    <color code="COM">Chrome</color>
    <color code="CPR">Copper</color>
    <color code="CRM">Cream</color>
    <color code="Gold">Gold</color>
    <color code="GRY">Gray</color>
    <color code="GRN">Green</color>
    <color code="DGR">Green (Dark)</color>
    <color code="LGR">Green (Light)</color>
    <color code="CRM">Ivory</color>
    <color code="LAV">Lavender</color>
    <color code="MAR">Maroon</color>
    <color code="MVE">Mauve</color>
    <color code="ONG">Orange</color>
    <color code="PNK">Pink</color>
    <color code="PLE">Purple</color>
    <color code="RED">Red</color>
    <color code="SIL">Silver</color>
    <color code="COM">Stainless Steel</color>
    <color code="TAN">Tan</color>
    <color code="TPE">Taupe</color>
    <color code="TEA">Teal</color>
    <color code="TRQ">Turquoise</color>
    <color code="WHI">White</color>
    <color code="YEL">Yellow</color>
    <color code="MUL/COL">Multicolor</color>
</codes:colors>

</xsl:stylesheet>

请注意,我还有两个未解决的问题:

    代码SIL 有两个条目:一个代表铝,一个代表银;

    Multicolor 的代码是MUL/COL - 这与所述原则相冲突:

    如果车辆不止一种颜色,则两种颜色代码将用斜线分隔。

【讨论】:

谢谢迈克尔这真的很有帮助。也感谢您的详细解释。

以上是关于基于一定条件的xml数据到xsl文件的转换的主要内容,如果未能解决你的问题,请参考以下文章

基于另一个变量的 XSLT 元素选择

基于不同行项目的分组 xsl1.0

带有 Quartz 作业的 XSL 样式表路径

哪个浏览器可以显示由XSLT转换的XML数据?

从简单 XML 文件到 XForms 的 XSL 转换并应用 CSS

使用 XSL 转换合并两个 XML 文件