Генерация XSLT для сопоставления структур значений источника с полем назначения в зависимости от содержимого источника - PullRequest
2 голосов
/ 29 февраля 2012

У меня есть исходный список XML в этом формате:

<metadata>
  <metadatum>
    <description>OnEnter</description>
    <value>Hello World</id>
  </metadatum>
  <metadatum>
    <description>OnLeave</description>
    <value>Goodbye World</id>
  </metadatum>
</metadata>

и целевая структура, подобная этой:

<friendlyText>
  <onEnter>[Content Here]</onEnter>
  <onLeave>[Content Here]</onLeave>
</friendlyText>

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

Я пытаюсь сделать это с помощью Altova MapForce; Такое ощущение, что должен быть интерфейс для этого, я просто не могу его найти.

Ответы [ 2 ]

1 голос
/ 29 февраля 2012
<?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="metadata">
    <friendlyText>
      <xsl:apply-templates select="metadatum"/>
    </friendlyText>  
  </xsl:template>

  <xsl:template match="metadatum">
    <xsl:element name="{description}">
      <xsl:value-of select="value"/>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

Выход:

<?xml version="1.0" encoding="utf-8"?>
<friendlyText>
  <OnEnter>Hello World</OnEnter>
  <OnLeave>Goodbye World</OnLeave>
</friendlyText>
0 голосов
/ 29 февраля 2012

Это преобразование является общим решением, которое может работать с любой "целевой структурой", которая находится в отдельном XML-документе :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" exclude-result-prefixes="my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vUpper" select=
  "'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
 <xsl:variable name="vLower" select=
  "'abcdefghijklmnopqrstuvwxyz'"/>

 <my:target>
  <friendlyText>
    <onEnter>[Content Here]</onEnter>
    <onLeave>[Content Here]</onLeave>
  </friendlyText>
 </my:target>

 <xsl:variable name="vTarget" select="document('')/*/my:target/*"/>

 <xsl:variable name="vMeta" select="/*/metadatum"/>

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

 <xsl:template match="/">
     <xsl:apply-templates select="$vTarget"/>
 </xsl:template>

 <xsl:template match="friendlyText/*/text()">
  <xsl:value-of select=
  "$vMeta[translate(description, $vLower, $vUpper)
        =
          translate(name(current()/..), $vLower, $vUpper)
          ]/value"/>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML (исправлено, чтобы оно было правильно оформлено):

<metadata>
    <metadatum>
        <description>OnEnter</description>
        <value>Hello World</value>
    </metadatum>
    <metadatum>
        <description>OnLeave</description>
        <value>Goodbye World</value>
    </metadatum>
</metadata>

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

<friendlyText xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="my:my">
   <onEnter>Hello World</onEnter>
   <onLeave>Goodbye World</onLeave>
</friendlyText>

Примечание: : только для удобства «целевая структура» здесь встроена. В реальных условиях было бы лучше сохранить «целевую структуру» в отдельном файле и загрузить ее с помощью функции document(). Только строка:

 <xsl:variable name="vTarget" select="document('')/*/my:target/*"/>

нужно будет изменить на:

 <xsl:variable name="vTarget" select="document('someFileUrl')/*"/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...