Dodawanie atrybutu do węzła
Próbuję dodać atrybut do węzła, jeśli wartość węzła potomnego jest równa jakiemuś łańcuchowi znaków.
Mam główną.plik xml<Employees>
<Employee>
<countryid>32</countryid>
<id name="id">1</id>
<firstname >ABC</firstname>
<lastname >XYZ</lastname>
</Employee>
<Employee>
<countryid>100</countryid>
<id name="id">2</id>
<firstname >ddd</firstname>
<lastname >ggg</lastname>
</Employee>
</Employees>
Powiedzmy więc, że jeśli identyfikator kraju jest równy 32, to powinien dodać atrybut country=32 do węzła pracownika. Wyjście powinno być jak poniżej:
Wyjście.xml
<Employees>
<Employee countryid="32">
<countryid>32</countryid>
<id name="id">1</id>
<firstname >ABC</firstname>
<lastname >XYZ</lastname>
</Employee>
<Employee>
<countryid>100</countryid>
<id name="id">2</id>
<firstname >ddd</firstname>
<lastname >ggg</lastname>
</Employee>
</Employees>
Używam poniższego skryptu, ale pojawia się błąd, że węzeł atrybutu nie może być utworzony po element.:
Transformacja.xsl
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="Employees/Employee/countryid[.=32']">
<xsl:attribute name="countryid">32</xsl:attribute>
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
Każda pomoc będzie mile widziana. Również możemy przekazać countryid jako wartości rozdzielone przecinkami tak, że mogę przekazać 32,100, a następnie powinien dodać atrybut do wszystkich pasujących węzłów.
Dzięki. 2 answers
Poza dobrą odpowiedzią Dimitre ' a, arkusz stylów XSLT 2.0:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="pCountry" select="'32,100'"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Employee[countryid = tokenize($pCountry,',')]">
<Employee countryid="{countryid}">
<xsl:apply-templates select="@*|node()"/>
</Employee>
</xsl:template>
</xsl:stylesheet>
Wyjście:
<Employees>
<Employee countryid="32">
<countryid>32</countryid>
<id name="id">1</id>
<firstname>ABC</firstname>
<lastname>XYZ</lastname>
</Employee>
<Employee countryid="100">
<countryid>100</countryid>
<id name="id">2</id>
<firstname>ddd</firstname>
<lastname>ggg</lastname>
</Employee>
</Employees>
Notatka : Existencial comparison with sequence, param / variable reference in patterns.
Inne podejście przy założeniu, że countryid
jest zawsze pierwszym dzieckiem:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:param name="pCountry" select="'32,100'"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="countryid[. = tokenize($pCountry,',')]">
<xsl:attribute name="countryid">
<xsl:value-of select="."/>
</xsl:attribute>
<xsl:call-template name="identity"/>
</xsl:template>
</xsl:stylesheet>
Uwaga : Teraz xsl:strip-space
instrukcja jest ważna (unika węzła tekstu wyjściowego przed atrybutem)
Część 1 .
Więc powiedzmy, że identyfikator kraju jest równe 32 wtedy należy dodać atrybut country = 32 To Employee node.
Ta transformacja :
<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:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Employee[countryid=32]">
<Employee countryid="{countryid}">
<xsl:apply-templates select="@*|node()"/>
</Employee>
</xsl:template>
</xsl:stylesheet>
W przypadku zastosowania na dostarczonym dokumencie XML :
<Employees>
<Employee>
<countryid>32</countryid>
<id name="id">1</id>
<firstname >ABC</firstname>
<lastname >XYZ</lastname>
</Employee>
<Employee>
<countryid>100</countryid>
<id name="id">2</id>
<firstname >ddd</firstname>
<lastname >ggg</lastname>
</Employee>
</Employees>
Tworzy pożądany, poprawny wynik :
<Employees>
<Employee countryid="32">
<countryid>32</countryid>
<id name="id">1</id>
<firstname>ABC</firstname>
<lastname>XYZ</lastname>
</Employee>
<Employee>
<countryid>100</countryid>
<id name="id">2</id>
<firstname>ddd</firstname>
<lastname>ggg</lastname>
</Employee>
</Employees>
Wyjaśnienie :
Reguła identity rule jest używana do kopiowania każdego węzła jako-is. Używanie i nadpisywanie reguły tożsamości (szablonu) jest najbardziej fundamentalnym i potężnym wzorcem projektowym XSLT.
Istnieje tylko jeden szablon, który nadpisuje regułę tożsamości dla określonych węzłów --
Employee
elementy, które mają potomekcountryid
z wartością łańcuchową (przekonwertowaną na liczbę) 32. Ten szablon dodaje atrybutcountryid
do elementuEmployee
i stosuje szablony, aby wznowić aktywność reguły tożsamości i skopiować Wszystko inne tak, jak jest.
Część 2.
Możemy również przekazać countryid jako przecinek seprated wartości tak, że mogę przejść 32,100, a następnie należy dodać atrybut do wszystkich pasujących węzłów
Ta transformacja :
<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="pIds" select="'32,100'"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Employee">
<Employee>
<xsl:if test=
"contains(concat(',',$pIds,','),
concat(',',countryid,',')
)">
<xsl:attribute name="countryid">
<xsl:value-of select="countryid"/>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="@*|node()"/>
</Employee>
</xsl:template>
</xsl:stylesheet>
Po zastosowaniu do tego samego dokumentu XML (powyżej), generuje pożądany, poprawny wynik :
<Employees>
<Employee countryid="32">
<countryid>32</countryid>
<id name="id">1</id>
<firstname>ABC</firstname>
<lastname>XYZ</lastname>
</Employee>
<Employee countryid="100">
<countryid>100</countryid>
<id name="id">2</id>
<firstname>ddd</firstname>
<lastname>ggg</lastname>
</Employee>
</Employees>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-28 05:18:25