0

私は XSLT が初めてです。25 を超える XML に続く ID の現在の int を、1 ~ 25 の範囲の一意の ID に更新しようとしています。

* MYXML *

<Root>
<Properties>
<Props></Props>
<Input>
</Input>
<Profile InstanceID ="4" ObjectID="XYZ"> (no need to update these instanceID)
<ELM_INT>Profile 1</ELM_INT>
<Video **InstanceID="26"** ObjectID="ABC" Type="103"></Video>   
<Audio **InstanceID="1"** ObjectID="DEF" Type="103"></Audio>
<Audio **InstanceID="27"** ObjectID="GHI" Type="103"></Audio>      
<Output ObjectID="JKL" Type="104" Type="25"></Output>
</Profile>
</Properties>

<Properties>
<Props></Props>
<Input>
</Input>
<Profile InstanceID ="4" ObjectID="XYZ"> (no need to update these instanceID)
<ELM_INT>Profile 1</ELM_INT>
<Video **InstanceID="33"** ObjectID="MNO" Type="103"></Video>
<Audio **InstanceID="25"** ObjectID="PQR" Type="103"></Audio>
<Audio **InstanceID="2"** ObjectID="EFG" Type="103"></Audio>      
<Output ObjectID="HIJ" Type="104" Type="25"></Output>
</Profile>
</Properties>
</Root>

私の XSLT

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">

<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>

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

<!--Get all instance id's includng Profile and call loop-->
<xsl:for-each select="@*/..">
<!--Id instanceId is greater than 25 than call loop-->
<xsl:variable name="CurrentInstanceID">
<xsl:value-of select="@InstanceID"/>
</xsl:variable>


<xsl:if test="$CurrentInstanceID &gt; 25">
<!--<xsl:text> .Calling Iterate1To25 </xsl:text>-->  
<xsl:call-template name="Iterate1To25">
<xsl:with-param name="pStart" select="1"/>
<xsl:with-param name="pEnd" select="25"/>
</xsl:call-template>
</xsl:if>

</xsl:for-each>

</xsl:template>
<!--Main END-->

<!-- Iterate1To25which iterate for 25 times START-->
<xsl:template name="Iterate1To25" >
<xsl:param name="pStart"/>
<xsl:param name="pEnd"/>

<xsl:if test="not($pStart &gt; $pEnd)">

<xsl:variable name="serchAudeoInstanceID">
<xsl:value-of select="count(../Audio[@InstanceID=$pStart])"/>
</xsl:variable>

<xsl:variable name="serchVideoInstanceID">
<xsl:value-of select="count(../Video[@InstanceID=$pStart])"/>
</xsl:variable>

<xsl:choose>
<xsl:when test="$serchAudeoInstanceID &gt; 0 or $serchVideoInstanceID &gt; 0>
<xsl:call-template name="Iterate1To25">
<xsl:with-param name="pStart" select="$pStart+1"/>
<xsl:with-param name="pEnd" select="25"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!--pStart can be assigned-->
<xsl:element name="Valid_ID">
<xsl:value-of select="$pStart"/>
<xsl:attribute name="InstanceID">
<xsl:value-of select="$pStart"/>
</xsl:attribute>
</xsl:element>

</xsl:otherwise>
</xsl:choose>

</xsl:if>

</xsl:template>

</xsl:stylesheet>

OUTPUT/変換された XML

<Root>
<Properties>
<Props></Props>
<Input>
</Input>
<Profile_InstanceID ="4" ObjectID="XYZ">
<ELM_INT>Profile 1</ELM_INT>

<Video **InstanceID="26"** ObjectID="ABC" Type="103"></Video> 
****<ValidID>2</ValidID>****

<Audio **InstanceID="1"** ObjectID="DEF" Type="103"></Audio>

<Audio **InstanceID="27"** ObjectID="GHI" Type="103"></Audio>      
****<ValidID>2</ValidID> (expected 3)****

<Output ObjectID="JKL" Type="104" Type="25"></Output>
</Profile_Instance>
</Properties>

<Properties>
<Props></Props>
<InputTransport>
</InputTransport>
<Profile_InstanceID ="4" ObjectID="XYZ">
<ELM_INT>Profile 1</ELM_INT>

<Video **InstanceID="33"** ObjectID="MNO" Type="103"></Video>
****<ValidID>1</ValidID>****

<Audio **InstanceID="25"** ObjectID="PQR" Type="103"></Audio>

<Audio **InstanceID="2"** ObjectID="EFG" Type="103"></Audio>      

<Output ObjectID="HIJ" Type="104" Type="25"></Output>
</Profile_Instance>
</Properties>
</Root>

クエリ 1. 要素を追加する代わりに属性 InstanceID を更新する方法

事前に感謝します。

4

2 に答える 2

1

ID テンプレートを使用して正しい方法で開始しましたが、次に何をしようとしているのかわかりません。あなたはこれを持っています:

match="Profile/*"

Profileしかし、ソース ドキュメントで名前が付けられた要素が見当たりません。問題の説明から私が期待することは、次のようなものです。

<xsl:template match="@InstanceID[. > 25]">
  <xsl:attribute name="InstanceId" select="xxxx"/>
</xsl:template>

ここで、xxxx は属性の新しい値です。それが問題の次の部分です。特に簡単ではありませんが、変数 $pstart を計算するためのすべてのロジックがあるようで、これが必要な値であるように思われるので、上記の xxxxx として使用してください。

于 2013-10-08T22:54:04.313 に答える
0

一意の ID を割り当てるという問題に対処してみましょう。これは非常に難しく、制約が多すぎる可能性があるため、実際の要件が何であるかを知っておくとよいでしょう。

私は、どの識別子が使用されているかを判断し、自由に使用できる識別子を含む XML ドキュメントを生成する初期パスから始めると思います。それはそれほど難しいことではありません: 基本的に (疑似コードで) 「for i in 1 to N where not(i present in input) return i」.

次に、識別子を変更する必要があるノードのリストを作成し、このリストを変数に入れます。次に、この変数をパラメーターとして使用して、ドキュメントのツリー ウォークを実行します。ノードがリストに存在する場合、リストの N 番目の項目として、識別子を「free-to-use」リストの N 番目の識別子である id に置き換えます。

XSLT 1.0 でこれを試みるつもりはありません。しかし、私は XSLT 1.0 では何も試みません。2.0 に慣れてしまえば、それは大変な作業に似すぎます。また、このアルゴリズムを XSLT コードに変換するように頼まないでください。自分でできない場合は、他の人にお金を払ってやってもらう必要があります。

于 2013-10-09T22:55:09.020 に答える