XSLT для копирования XML-документа и добавления атрибута плюс сгенерированное значение при определенных условиях - PullRequest
1 голос
/ 27 октября 2010

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

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

Документ XML довольно прост:

<A x="foo" y="bar" z="">
<B/>
<C/></A>

В основном, если присутствует атрибут "z".Затем новый атрибут должен быть добавлен к узлу "A".Значением атрибута должна быть текстовая строка со значениями «x» и «y», заменяемыми в определенных местах.Результат должен выглядеть следующим образом:

<A x="foo" y="bar" z="" new="values present are x=foo and y=bar">
<B/>
<C/></A>

Я дошел до создания XSLT, который будет копировать документ на уровень атрибута.Но я спотыкаюсь, пытаясь создать логику, которая проверяет атрибут z и создает строку на основе х и у.

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

Спасибо

Также- извиняюсь, если мой формат кода отстой

Из комментариев:

Есть что-то, что мешает этим решениям работать.Текст XML, который я поместил выше, на самом деле имеет корневой узел <R>, который содержит все это.Узел R имеет такой атрибут: xmlns="http://www.fixprotocol.org/FIXML-4-4".При добавлении этого атрибута по какой-то причине шаблон, соответствующий «A», не работает?!

Ответы [ 3 ]

3 голосов
/ 27 октября 2010

Обновлено : ОП объяснил (только в комментарии!):

Что-то останавливает эти решения работают. Текст XML Я поставил выше на самом деле имеет рут узел, который содержит все это. <R> узел имеет такой атрибут: xmlns="http://www.fixprotocol.org/FIXML-4-4". Добавление этого атрибута по какой-то причине вызывает сопоставление шаблона "A" не работает?!

Это, вероятно, так коротко, как это может быть :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:x="http://www.fixprotocol.org/FIXML-4-4"
 xmlns="http://www.fixprotocol.org/FIXML-4-4" exclude-result-prefixes="x">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

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

 <xsl:template match="x:A[@z]">
  <A new="values present are x={@x} and y={@y}">
   <xsl:apply-templates select="node()|@*"/>
  </A>
 </xsl:template>
</xsl:stylesheet>

когда это преобразование применяется к предоставленному документу XML :

<R xmlns="http://www.fixprotocol.org/FIXML-4-4">
    <A x="foo" y="bar" z="">
        <B/>
        <C/>
    </A>
</R>

желаемый, правильный результат выдается :

<R xmlns="http://www.fixprotocol.org/FIXML-4-4">
    <A new="values present are x=foo and y=bar" x="foo" y="bar" z="">
        <B></B>
        <C></C>
    </A>
</R>
1 голос
/ 27 октября 2010

РЕДАКТИРОВАТЬ : теперь с правильным пространством имен.

Эта таблица стилей:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:fixml="http://www.fixprotocol.org/FIXML-4-4">
    <xsl:template match="@*|node()" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="fixml:A/@z">
        <xsl:call-template name="identity"/>
        <xsl:attribute name="new">
            <xsl:value-of
               select="concat('values present are x=',../@x,' and y=',../@y)"/>
        </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

С этим входом:

<R xmlns="http://www.fixprotocol.org/FIXML-4-4">
    <A x="foo" y="bar" z="">
        <B/>
        <C/>
    </A>
</R>

Выход:

<R xmlns="http://www.fixprotocol.org/FIXML-4-4">
    <A x="foo" y="bar" z="" new="values present are x=foo and y=bar">
        <B></B>
        <C></C>
    </A>
</R>
1 голос
/ 27 октября 2010

Вы можете использовать следующие XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

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

  <xsl:template match="A">
    <A>
      <xsl:if test="@z">
        <xsl:attribute name="new">
         <xsl:value-of select="concat('values present are x=',@x,' and y=',@y)"/>
        </xsl:attribute>
      </xsl:if>
      <xsl:apply-templates select="@* | node()"/>
    </A>

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