Я недавно натолкнулся на следующий XML-тикер биржи:
<?xml version="1.0" encoding="utf-8"?>
<BloombergOutput>
<BloombergOutput CreatedUtc="2011-08-11T20:40:50.8851936Z">
<Instruments>
<Instrument Symbol="BLL">
<Fields>
<Field1 Name="LastPrice">
<Value>35.550000</Value>
</Field1>
<Field2 Name="NetChangeOneDay">
<Value>+1.550000</Value>
</Field2>
<Field3 Name="LastCloseDate">
<Value>08/11/2011</Value>
</Field3>
<Field4 Name="LastClosePrice">
<Value>35.550000</Value>
</Field4>
<Field5 Name="UpdateDate">
<Value>08/11/2011</Value>
</Field5>
<Field6 Name="UpdateTime">
<Value>16:15:03</Value>
</Field6>
<Field7 Name="LongName">
<Value>Ball Corp</Value>
</Field7>
<Field8 Name="Name">
<Value>BALL CORP</Value>
</Field8>
<Field9 Name="PriceSource">
<Value>US</Value>
</Field9>
<Field10 Name="SymbolType">
<Value>Common Stock</Value>
</Field10>
</Fields>
</Instrument>
</Instruments>
</BloombergOutput>
</BloombergOutput>
Я хотел использовать XSLT, чтобы преобразовать этот фид в то, что не имело ненужной вложенности тегов, имело более описательные имена элементов и урезало слишком длинные числа, чтобы у них было только два числа после десятичной точки. Вот XSLT, который я придумал:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- Identity Transform, modified to begin at the Instruments element -->
<xsl:template match="BloombergOutput/BloombergOutput/Instruments/@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- For each instrument, we grab the Symbol attribute and work on each child element -->
<xsl:template match="Instrument">
<Instrument>
<Symbol><xsl:value-of select="@Symbol" /></Symbol>
<xsl:apply-templates select="Fields/*" mode="fields" />
</Instrument>
</xsl:template>
<!-- For each child field, we create a newly-named one and give it a value -->
<xsl:template match="node()" mode="fields">
<xsl:variable
name="FieldName"
select="@Name" />
<xsl:variable
name="Value"
select="Value" />
<xsl:element name="{$FieldName}">
<xsl:choose>
<!-- For these fields, we only want to preserve to spots after the decimal point -->
<xsl:when test="$FieldName='LastPrice' or $FieldName='NetChangeOneDay' or $FieldName='LastClosePrice'">
<xsl:value-of select="concat(substring-before($Value, '.'), '.', substring(substring-after($Value, '.'), 1, 2))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$Value" />
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
... который производит этот вывод:
<?xml version="1.0"?>
<BloombergOutput>
<BloombergOutput>2011-08-11T20:40:50.8851936Z
<Instruments>
<Instrument>
<Symbol>BLL</Symbol>
<LastPrice>35.55</LastPrice>
<NetChangeOneDay>+1.55</NetChangeOneDay>
<LastCloseDate>08/11/2011</LastCloseDate>
<LastClosePrice>35.55</LastClosePrice>
<UpdateDate>08/11/2011</UpdateDate>
<UpdateTime>16:15:03</UpdateTime>
<LongName>Ball Corp</LongName>
<Name>BALL CORP</Name>
<PriceSource>US</PriceSource>
<SymbolType>Common Stock</SymbolType>
</Instrument>
</Instruments>
</BloombergOutput>
</BloombergOutput>
Хотя это почти то, что я хочу, есть некоторые проблемы:
- Дополнительный элемент
BloombergOutput
сверху сохраняется; кроме того, его параметр CreatedUtc
сохраняется довольно странным образом. Мое первоначальное намерение состояло в том, чтобы полностью удалить ненужные теги BloombergOutput
.
- Я успешно вставил добавление тега
Instrument
.
Тем не менее, Instruments
сохраняется без того, чтобы я прямо сказал об этом.
Я понимаю, что преобразование идентичности принесло его, потому что я не сделал
скажи, чтобы это ушло, но что, если бы я хотел разные открывающие элементы
(скажем, StockQuote
)?
- Мое намерение состояло в том, чтобы научиться использовать Identity Transform.
Тем не менее, я не уверен, что моя модификация матча является правильной
способ сделать то, что я делаю.
В целом, я ищу ваш совет эксперта о том, как улучшить это. Не стесняйтесь сказать мне, что я пытаюсь использовать шаблон дизайна, который ему не подходит. :)
Большое спасибо.