1

直面している問題を解決するのに非常に苦労しています。XSLTを使用してターゲットスキーマに変換するソースXMLスキーマがあります。ただし、ターゲットスキーマの要素の1つは、ソースXML(属性を含む)からの生のXMLを保持するように設計されています。データが再び消費されるときに問題が発生するため、CDATAを使用したくありません。このXSLTはBizTalk2009で実行しているため、XSLT 1.0 /XPATH1.0の使用のみに制限されます。

ああ、そしてもう少し複雑にするために、ソースXMLのデータにはいくつかの要素に<と>が含まれています。

ソースの例:

<root>
<foo company="1">
    <bar id="125" title="foobar3">
    &gt; 15 years
</bar>
    <bar id="126" title="foobar4">
    &lt; 5 years
</bar>
</foo>
<foo company="2">
    <bar id="125" title="foobar3">
    &gt; 15 years
</bar>
    <bar id="126" title="foobar4">
    &lt; 5 years
</bar>
</foo>

ターゲットの例

<newXML>
    <Company>1</Company>
    <SourceXML>
&lt;root&gt;
    &lt;foo company="1"&gt;
        &lt;bar id="125" title="foobar3"&gt;
        "&gt;" 15 years
    &lt;/bar&gt;
        &lt;bar id="126" title="foobar4"&gt;
        "&lt;" 5 years
    &lt;/bar&gt;
    &lt;/foo&gt;
    &lt;foo company="2"&gt;
        &lt;bar id="125" title="foobar3"&gt;
        "&gt;" 15 years
    &lt;/bar&gt;
        &lt;bar id="126" title="foobar4"&gt;
        "&lt;" 5 years
    &lt;/bar&gt;
    &lt;/foo&gt;
&lt;/root&gt;   
    </SourceXML>
</newXML>
4

1 に答える 1

1

それほど複雑ではありません。目的のテキスト表現を出力ツリーに書き込む要素ノードと属性ノードの2つのテンプレートを作成する必要があります。<テキストノードで引用符を使用して折り返すだけで>、もう少し入力が必要になります。スタイルシートは次のようになります。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/">
      <newXML>
         <Company>1</Company>
         <SourceXML>
            <xsl:apply-templates/>
         </SourceXML>
      </newXML>
   </xsl:template>

   <xsl:template match="*">
      <xsl:value-of select="concat('&lt;',name())"/>
      <xsl:apply-templates select="@*"/>
      <xsl:text>&gt;</xsl:text>
      <xsl:apply-templates select="node()"/>
      <xsl:value-of select="concat('&lt;/',name(), '>')"/>
   </xsl:template>

   <xsl:template match="@*">
      <xsl:value-of select="concat(' ', name(),'=','&quot;', ., '&quot;')"/>
   </xsl:template>

   <xsl:template match="text()">
      <xsl:call-template name="wrap">
         <xsl:with-param name="str">
            <xsl:call-template name="wrap">
               <xsl:with-param name="str" select="."/>
               <xsl:with-param name="find" select="'&lt;'"/>
            </xsl:call-template>
         </xsl:with-param>
         <xsl:with-param name="find" select="'&gt;'"/>
      </xsl:call-template>
   </xsl:template>

   <xsl:template name="wrap">
      <xsl:param name="str"/>
      <xsl:param name="find"/>
      <xsl:choose>
         <xsl:when test="contains($str, $find)">
            <xsl:variable name="before" select="substring-before($str, $find)"/>
            <xsl:variable name="after" select="substring-after($str, $find)"/>
            <xsl:value-of select="concat($before, '&quot;', $find, '&quot;')"/>
            <xsl:call-template name="wrap">
               <xsl:with-param name="str" select="$after"/>
               <xsl:with-param name="find" select="$find"/>
            </xsl:call-template>
         </xsl:when>
         <xsl:otherwise>
            <xsl:value-of select="$str"/>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>
</xsl:stylesheet>
于 2012-05-09T20:19:46.493 に答える