2013-09-27 7 views
0

У меня есть следующий XML-файл:Изменение значений атрибутов с помощью XSL

<xc:XmlCache xmlns:xc="XmlCache" xmlns:mp="mx.MarketParameters" xmlns:fx="mx.MarketParameters.Forex" xmlns:fxsp="mx.MarketParameters.Forex.Spot"> 
<xc:XmlCacheArea xc:value="MarketParameters"> 
    <mp:nickName xc:value="MDS" xmlns:mp="mx.MarketParameters"> 
    <mp:date xc:value="20130315"> 
    <fx:forex xmlns:fx="mx.MarketParameters.Forex"> 
    <fxsp:spot xmlns:fxsp="mx.MarketParameters.Forex.Spot"> 
     <fxsp:pair xc:value="AUD/AED" xc:type="Fields"> 
     <mp:ask xc:keyFormat="N">1.0000000</mp:ask> 
     <mp:bid xc:keyFormat="N">1.0000000</mp:bid> 
     <mp:formFactor xc:keyFormat="N">1</mp:formFactor> 
     <mp:high xc:keyFormat="N">0.0000000</mp:high> 
     <mp:low xc:keyFormat="N">0.0000000</mp:low> 
     <mp:mid xc:keyFormat="N">1.0000000</mp:mid> 
     <mp:quotation xc:keyFormat="C">AUD-AED</mp:quotation> 
     </fxsp:pair> 
     <fxsp:pair xc:value="BHD/AED" xc:type="Fields"> 
     <mp:ask xc:keyFormat="N">0.8264463</mp:ask> 
     <mp:bid xc:keyFormat="N">0.8264463</mp:bid> 
     <mp:formFactor xc:keyFormat="N">1</mp:formFactor> 
     <mp:high xc:keyFormat="N">0.0000000</mp:high> 
     <mp:low xc:keyFormat="N">0.0000000</mp:low> 
     <mp:mid xc:keyFormat="N">0.8264463</mp:mid> 
     <mp:quotation xc:keyFormat="C">BHD-AED</mp:quotation> 
     </fxsp:pair> 
    </fxsp:spot> 
    </fx:forex> 
    </mp:date> 
    </mp:nickName> 
</xc:XmlCacheArea> 
</xc:XmlCache> 

Я ищу способ сделать две вещи: 1. Удалите все элементы, но два -> Тпл: спросить и Тпл: bid 2. измените числовые значения этих двух элементов на другие значения, которые у меня есть в файле csv.

Ожидаемый выход

<xc:XmlCache xmlns:xc="XmlCache" xmlns:mp="mx.MarketParameters" xmlns:fx="mx.MarketParameters.Forex" xmlns:fxsp="mx.MarketParameters.Forex.Spot"> 
<xc:XmlCacheArea xc:value="MarketParameters"> 
<mp:nickName xc:value="MDS" xmlns:mp="mx.MarketParameters"> 
<mp:date xc:value="20130315"> 
<fx:forex xmlns:fx="mx.MarketParameters.Forex"> 
<fxsp:spot xmlns:fxsp="mx.MarketParameters.Forex.Spot"> 
<fxsp:pair xc:value="AUD/AED" xc:type="Fields"> 
<mp:ask xc:keyFormat="N">1.0000000</mp:ask> 
<mp:bid xc:keyFormat="N">1.0000000</mp:bid> 
</fxsp:pair> 
<fxsp:pair xc:value="BHD/AED" xc:type="Fields"> 
<mp:ask xc:keyFormat="N">0.8264463</mp:ask> 
<mp:bid xc:keyFormat="N">0.8264463</mp:bid> 
</fxsp:pair> 
</fxsp:spot> 
</fx:forex> 
</mp:date> 
</mp:nickName> 
</xc:XmlCacheArea> 
</xc:XmlCache> 

Идея заключается в том, чтобы обновить значения в выходной XML с теми, предусмотренными в файле CSV (первое значение ставки, второй один, это спросить). Если необходимо, файл csv может быть преобразован в xml, это не проблема.

CSV file 
AUD/AED;25;25 
BHD/AED;20;20 

Файл сделан из приложения, которое мы используем. После изменения значений цель состоит в том, чтобы повторно импортировать файл в приложение. Я пробовал много вещей в xsl, но должен сказать, что не вижу, как я могу заставить его работать.

Может ли кто-нибудь помочь?

Благодаря

+0

Можно ли изменить свой вопрос, чтобы показать результат, который вы ожидаете здесь? Кроме того, не могли бы вы уточнить, что вы имеете в виду, когда говорите «другие значения, которые у меня есть в файле CSV». Возможно, вы также можете показать этот файл CSV, хотя я боюсь, что извлечение значений из него с помощью XSLT может быть сложным (вам почти наверняка понадобится использовать XSLT 2.0) –

ответ

0

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

<csv> 
    <record code="AUD/AED" bid="25" ask="25" /> 
    <record code="BHD/AED" bid="20" ask="20" /> 
</csv> 

С точки зрения делает преобразование, если вы не сделали, вы должны строить на идентичность XSLT преобразования для копирования все существующие узлы в начале.

<xsl:template match="@*|node()"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

Это означает, что вам нужно написать дополнительные шаблоны для узлов/атрибутов, которые вы хотите изменить.

Вы говорите, что хотите удалить все (листья) элементы, кроме «ставка» и «спросить», ну, вы можете написать шаблон, как это, чтобы игнорировать все остальные

<xsl:template match="fxsp:pair/*[not(self::mp:ask) and not(self::mp:bid)]" /> 

Единственный другой шаблон вам нужно, это один, который соответствует текстовым узлам в любых других элементах, которые не исключены (т.е. это только теперь соответствует вашему «спросить» и элементы «ставки»)

<xsl:template match="fxsp:pair/*/text()"> 

в течение этого вы можете сделать ваш поиск от 'lookup'

<xsl:value-of select="document('lookup.xml')//record[@code=$code]/@*[local-name()=$attr]"/> 

В этом случае $ код устанавливается в значение атрибута хс: значение из fxsp: пары и $ атр это имя текущего элемента («просить» или ' ставка ").

Попробуйте этот XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xc="XmlCache" xmlns:mp="mx.MarketParameters" xmlns:fx="mx.MarketParameters.Forex" xmlns:fxsp="mx.MarketParameters.Forex.Spot"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="fxsp:pair/*[not(self::mp:ask) and not(self::mp:bid)]" /> 

    <xsl:template match="fxsp:pair/@xc:type" /> 

    <xsl:template match="fxsp:pair/*/text()"> 
    <xsl:variable name="code" select="../../@xc:value" /> 
    <xsl:variable name="attr" select="local-name(..)" /> 
    <xsl:value-of select="document('lookup.xml')//record[@code=$code]/@*[local-name()=$attr]"/> 
    </xsl:template> 
</xsl:stylesheet> 

Примечание, вы можете поместить «документ» ссылку на переменную, которая может упростить (и действительно улучшить эффективность).Попробуйте этот XSLT слишком

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xc="XmlCache" xmlns:mp="mx.MarketParameters" xmlns:fx="mx.MarketParameters.Forex" xmlns:fxsp="mx.MarketParameters.Forex.Spot"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:variable name="lookup" select="document('lookup.xml')//record" /> 

    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="fxsp:pair/*[not(self::mp:ask) and not(self::mp:bid)]" /> 

    <xsl:template match="fxsp:pair/@xc:type" /> 

    <xsl:template match="fxsp:pair/*/text()"> 
    <xsl:variable name="code" select="../../@xc:value" /> 
    <xsl:variable name="attr" select="local-name(..)" /> 
    <xsl:value-of select="$lookup[@code=$code]/@*[local-name()=$attr]"/> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Я также хотел бы удалить атрибут xc: type из элемента fxsp: pair , Я попытался добавить , но это не работает. Что я делаю не так? – user2822894

+0

Добавление, которое должно работать, если вы не добавили другие шаблоны, которые соответствуют тому же атрибуту, который имеет приоритет, или, может быть, есть код, который делает ** xsl: copy-of ** для атрибутов, а не ** xsl: apply- шаблоны **. В любом случае, я изменил свои примеры, включив эту строку, и оба примера работают должным образом. –

+0

Последний вопрос. Будет ли способ не изменять значения, когда код недоступен в файле поиска? Теперь каждый раз, когда вас нет, я не получаю никакой ценности. – user2822894

Смежные вопросы