Преобразуйте атрибуты в элементы - PullRequest
0 голосов
/ 30 апреля 2019

Я ненавижу писать XSLT, в основном потому, что я не очень хорош в этом.У меня есть файл данных XML, где все является атрибутом, а не прямым значением в значимом узле.

Я хотел бы запустить преобразование XSLT, которое могло бы превратить это:

<token-value-entry token-name="RECIPIENT_CITY">
<token-value><value>ROSEBURG</value></token-value>
</token-value-entry>
<token-value-entry token-name="RECIPIENT_STATE">
<token-value><value>OR</value></token-value>
</token-value-entry>

В это:

<RECIPIENT_CITY>ROSEBURG</<RECIPIENT_CITY>
<RECIPIENT_STATE>OR</RECIPIENT_STATE>

Хорошо, еще одно редактирование.Когда стекопотоки становятся педантичными?

Конкретный вопрос: есть ли способ использовать значение атрибута в качестве имени нового элемента?

У меня есть этот XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>

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

  <xsl:template match="@token-name">
    <xsl:element name="{name()}"><xsl:value-of select="."/></xsl:element>
  </xsl:template>
</xsl:stylesheet>

Который дает такой вывод:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <token-value-entry>
        <token-name>RECIPIENT_CITY</token-name>
        <token-value>
            <value>ROSEBURG</value>
        </token-value>
    </token-value-entry>
    <token-value-entry>
        <token-name>RECIPIENT_STATE</token-name>
        <token-value>
            <value>OR</value>
        </token-value>
    </token-value-entry>
</root>

Вопрос, на который я хотел бы получить ответ, помимо "держать в гугле", заключается в том, что я использую вместо переменной {name ()} для выводазначение "RECIPIENT_CITY" в качестве имени узла?

А пока, если я получу доступ к этому выводу, я, вероятно, смогу выяснить остальное:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <token-value-entry>
        <RECIPIENT_CITY />
        <token-value>
            <value>ROSEBURG</value>
        </token-value>
    </token-value-entry>
    <token-value-entry>
        <RECIPIENT_STATE />
        <token-value>
            <value>OR</value>
        </token-value>
    </token-value-entry>
</root>

Спросил другой способ, как я могу сохранить значение атрибута в переменной, которую я могу использовать в другом месте для создания элемента?

Ответы [ 4 ]

1 голос
/ 30 апреля 2019

Изменить

  <xsl:template match="@token-name">
    <xsl:element name="{name()}"><xsl:value-of select="."/></xsl:element>
  </xsl:template>

на

  <xsl:template match="token-value-entry">
    <xsl:element name="{@token-name}"><xsl:value-of select="."/></xsl:element>
  </xsl:template>
0 голосов
/ 01 мая 2019

Много предположений здесь. Возможно я не хочу изучать язык, но пытаюсь решить изолированную проблему, в то время как сотрудник отсутствует? Может быть, я консультант, просто пытающийся сделать проверку концепции, а «настоящий кодер» сделает тяжелую работу? Возможно, я изучил XML / XSLT 15 лет назад, и мне просто нужно освежиться?

В любом случае, решение, которое я придумал, таково:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>

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

    <xsl:template match="token-value-entry">
      <xsl:element name="{@token-name}">
        <xsl:apply-templates />
      </xsl:element>
    </xsl:template>

</xsl:stylesheet>

Исходный XML имеет несколько <token-value-entry token-name="xxx"><token-value><value>My Value</value></token-value></token-value-entry> конструкций, некоторые из которых вложены в другие <token-value-entry> родительские узлы.

<token-value-entry token-name="RECIPIENT_STATE">
                    <token-value>
                        <value>OR</value>
                    </token-value>
                </token-value-entry>
                <token-value-entry token-name="CNSMR_ACCNTS">
                    <token-value>
                        <list-of-values>
                            <token-value-entry token-name="ACCNT_CURBAL">
                                <token-value>
                                    <value>.73</value>
                                </token-value>

Моя цель состояла в том, чтобы включить каждый экземпляр:

<token-value-entry token-name="SOME_VALUE">...</token-value-entry>

В

<SOME_VALUE>...</SOME_VALUE>

И люди, которые комментировали и давали ссылки, помогли мне преодолеть концептуальное препятствие. Часть, которую мне нужно было переучить, состояла в том, как использовать переменные в xsl, а теперь выбирать целые узлы, а не только текстовые значения. Спасибо.

0 голосов
/ 01 мая 2019

Поскольку вы подняли несколько мета-вопросов о том, как подойти к проблеме, позвольте мне попытаться ответить на них.

Я думаю, что есть проблема с вашим подходом к изучению языка.Ответ, конечно же, не в том, чтобы «продолжать гуглить»: напротив, я думаю, что вы пытались решить свои проблемы, прибегая к поиску ответа, не садясь и не систематически изучая понятия языка.

Вот почему вы разочарованы процессом.

Ваш вопрос "есть ли способ использовать значение атрибута в качестве имени нового элемента?"иллюстрирует это.Если вы знаете, как использовать @xxx для получения значения атрибута, и если вы знаете, как использовать xsl:element для создания элемента, то у вас не должно возникнуть проблем при объединении двух идей.

Если вы используете Google и дадите ему описание вашей проблемы, то он найдет ответ, только если кто-то решил ту же проблему и описал ее в тех же терминах.Кто-то другой мог бы решить немного другую проблему, для решения которой требуются одни и те же примитивы, или они могли бы описать ее другими терминами, и вы не найдете информацию.И если вы найдете ответ, он, вероятно, будет описан в терминах понятий и терминологии, которые вы не освоили, потому что все ваши знания были получены случайными блоками, некоторые из которых написаны людьми, которые на самом деле имеют очень небольшую компетенцию.

Найдите себе хорошую книгу по языку и прочитайте ее, начиная с самого начала и изучая примеры.Автор позаботится о порядке представления тем, чтобы каждая глава основывалась на том, что вы узнали в предыдущих главах.Он научит вас строительным блокам, с которыми вы можете работать, и даст вам примеры того, как их объединить для решения проблем, некоторые из них похожи на ваши собственные, некоторые совсем другие.

Необходимые строительные блокиздесь все очень просто, и вы уже используете их, но мне кажется, что вы используете их, не понимая их по-настоящему;Я подозреваю, что вы скопировали код, который вы нашли в Google и не поняли.Это не правильная стратегия.

0 голосов
/ 30 апреля 2019

Если вы находитесь в контексте:

<xsl:for-each select="token-value-entry">

или:

<xsl:template match="token-value-entry">

, тогда инструкция:

<xsl:element name="{@token-name}">
    <!-- content here --> 
</xsl:element>

создаст нужный элемент(при условии, что атрибут token-name содержит допустимое имя элемента XML).

Чтобы понять, как это работает, прочитайте: https://www.w3.org/TR/1999/REC-xslt-19991116#attribute-value-templates.

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