1

特定のクライアント用に小さくしたい大きな入力XMLがあります。クライアントは、自分に関連する情報のみを表示する必要があります。入力例を次に示します。

<?xml version='1.0' encoding='UTF-8' ?>
<reg>
<global>stuff</global>
<profile>
<profile_data>profile stuff 1</profile_data>
<users>
<u><usr_data>usr options 1</usr_data><n>user-1</n></u>
<u><usr_data>usr options 2</usr_data><n>user-2</n></u>
</users>
</profile>
<profile>
<profile_data>profile stuff 2</profile_data>
<users>
<u><usr_data>usr options 3</usr_data><n>user-3</n></u>
<u><usr_data>usr options 4</usr_data><n>user-4</n></u>
</users>
</profile>
</reg>

これは、次のような小さなXMLに変換する必要があります。

<?xml version="1.0"?>
<reg>
<global>stuff</global>
<profile>
<profile_data>profile stuff 1</profile_data>
<users>
<u><usr_data>usr options 1</usr_data><n>user-1</n></u>
</users>
</profile>
</reg>

私はこれを、直列に適用された2つのXSLT変換(trans1.xml)を使用して達成することができました。

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="name"/>
<xsl:output method="xml"/>
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="/reg/profile">
    <xsl:if test="./users/*/n=$name">
        <xsl:copy-of select="." />
    </xsl:if>
</xsl:template>
</xsl:stylesheet>

および(trans2.xml):

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="name"/>
<xsl:output method="xml"/>
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="/reg/profile/users/*">
    <xsl:if test="./n=$name">
        <xsl:copy-of select="." />
    </xsl:if>
</xsl:template>
</xsl:stylesheet>

それで:

xsltproc -param name "'user-1'" trans1.xml input.xml > out1.xml
xsltproc -param name "'user-1'" trans2.xml out1.xml > result.xml

2つのXSlスタイルシートを1つに変換して、これら2つの操作を1つのステップで実行するにはどうすればよいですか。

4

1 に答える 1

0

この変換:

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

 <xsl:param name="pName" select="'user-1'"/>

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

 <xsl:template match="profile">
  <xsl:if test="users/u/n = $pName">
    <xsl:call-template name="identity"/>
  </xsl:if>
 </xsl:template>

 <xsl:template match="u">
  <xsl:if test="n = $pName">
   <xsl:call-template name="identity"/>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

提供された XML ドキュメントに適用した場合:

<reg>
    <global>stuff</global>
    <profile>
        <profile_data>profile stuff 1</profile_data>
        <users>
            <u>
                <usr_data>usr options 1</usr_data>
                <n>user-1</n>
            </u>
            <u>
                <usr_data>usr options 2</usr_data>
                <n>user-2</n>
            </u>
        </users>
    </profile>
    <profile>
        <profile_data>profile stuff 2</profile_data>
        <users>
            <u>
                <usr_data>usr options 3</usr_data>
                <n>user-3</n>
            </u>
            <u>
                <usr_data>usr options 4</usr_data>
                <n>user-4</n>
            </u>
        </users>
    </profile>
</reg>

必要な正しい結果が生成されます。

<reg>
   <global>stuff</global>
   <profile>
      <profile_data>profile stuff 1</profile_data>
      <users>
         <u>
            <usr_data>usr options 1</usr_data>
            <n>user-1</n>
         </u>
      </users>
   </profile>
</reg>

説明:

アイデンティティ ルールの適切な使用とオーバーライド。

于 2012-06-29T02:15:46.367 に答える