5

私は XSLT を初めて使用するので、これはおそらく非常に基本的なものですが、いくつかの情報を提供していただければ幸いです。XML で子ノードを変換する必要がありますが、同時に親ノードは変更されません。私のxmlは次のようになります:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<XMLTest xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xmlns:jfxpf="http://www.xfa.com/schema/xml-package" xmlns:xfa="http://www.xfa.com/schema/xfa-data">
    <result form="10"   version="4" resultid="23146" respondent="ycisxmir" authid="" date="2012-09-12 06:39:44" times="462">
        <Q0061 answerid="1">1</Q0061>
        <Q0060 answerid="2">2</Q0060>
        <QTXT1>1</QTXT1>
    </result>
</XMLTest>

上位 2 つのノード XMLTest と結果は変更せずに保持する必要がありますが、子ノードは次のようなより一般的な形式に変換する必要があります。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<XMLTest xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xmlns:jfxpf="http://www.xfa.com/schema/xml-package" xmlns:xfa="http://www.xfa.com/schema/xfa-data">
    <result form="10"   version="4" resultid="23146" respondent="ycisxmir" authid="" date="2012-09-12 06:39:44" times="462">
        <answer>Q0061</answer>
        <id>1</id>
        <value>1</value>
        <answer>Q0060</answer>
        <id>2</id>
        <value>2</value>
        <answer>QTXT1</answer>
        <value>1</value>
    </result>
</XMLTest>

これまでの私の xslt は次のようになります。

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>

    <xsl:template match="result/*">
        <answer><xsl:value-of select="local-name()"/></answer> 
        <id><xsl:value-of select="@answerid"/></id> 
        <value><xsl:value-of select="@*"/></value> 
    </xsl:template>  
</xsl:stylesheet>

最上位ノードで xsl:copy を使用しようとしましたが、子ノードまたは子ノードの変換を失うことなく機能させることはできません。最上位ノードを維持しながら、変換された子ノードを同時に通過させるにはどうすればよいですか?

4

2 に答える 2

3

皮切りに

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

必要な変換用のテンプレートを追加します。

<xsl:template match="result/*[@answerid]">
        <answer><xsl:value-of select="local-name()"/></answer> 
        <id><xsl:value-of select="@answerid"/></id> 
        <value><xsl:value-of select="."/></value>   
</xsl:template>

<xsl:template match="result/*[not(@answerid)]">
         <answer><xsl:value-of select="local-name()"/></answer> 
        <value><xsl:value-of select="."/></value>  
</xsl:template>
于 2012-11-23T10:17:15.080 に答える
1

ID テンプレートがありません:

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

私はあなたの答えを修正しました..:

<?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="/XMLTest/result/*">
    <answer>
      <xsl:value-of select="local-name()"/>
    </answer>
    <id>
      <xsl:value-of select="@answerid"/>
    </id>
    <value>
      <xsl:value-of select="@*"/>
    </value>
  </xsl:template>


</xsl:stylesheet>

Edit1: 属性が null の場合は破棄するように更新されたテンプレート: if 条件は、要素に変換する前に属性が null かどうかをチェックします。

  <xsl:template match="/XMLTest/result/*">
    <answer>
      <xsl:value-of select="local-name()"/>
    </answer>
    <xsl:if test="@answerid/.!=''">
      <id>
        <xsl:value-of select="@answerid"/>
     </id>
    </xsl:if>
    <xsl:if test="@*/.!=''">
    <value>
      <xsl:value-of select="@*"/>
    </value>
    </xsl:if>
  </xsl:template>

Edit2:あなたの初期の試みでは、@* の値をコピーしようとしていて@*、anyname の属性を示していたので、@answerid の値をコピーしていました (それが利用可能な唯一の属性だったので)..あなたがしなければならなかったことは .. valu-of=".". . 以下のコードを試してください..

  <xsl:template match="/XMLTest/result/*">
    <answer>
      <xsl:value-of select="local-name()"/>
    </answer>
    <xsl:if test="@answerid/.!=''">
      <id>
        <xsl:value-of select="@answerid"/>
     </id>
    </xsl:if>
    <xsl:if test=".!=''">
    <value>
      <xsl:value-of select="."/>
    </value>
    </xsl:if>
  </xsl:template>
于 2012-11-23T10:16:27.747 に答える