I have an XML looking like this:
<pack>
<titlesPacks>
<StoryPack id="1111111">
<value>A</value>
</StoryPack>
<StoryPack id="2222222">
<value>F</value>
</StoryPack>
</titlesPacks>
<referenceTable>
<TitleReference id="1111111" />
<TitleReference id="2222222" />
</referenceTable>
</pack>
I need to copy the xml file, but:
delete StoryPack
nodes where value
node has specific value (A, B, C for example). This part is already OK
delete 'TitleReferencenodes where
idattribute value is equal to
id attribute value of' StoryPack
nodes deleted above
I don't know how to do the second one: I tried with Key, but doesn't work:
My current XSL:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:data="http://example.com/data" exclude-result-prefixes="data">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="titleId" match="StoryPack" use="@id"/>
<!-- Values for which nodes must be deleted -->
<data:data xmlns="">
<value>A</value>
<value>B</value>
<value>C</value>
</data:data>
<xsl:variable name="values" select="document('')/xsl:stylesheet/data:data/value"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- Delete nodes with specific values -->
<xsl:template match="StoryPack[value = $values]"/>
<!-- Dlete nodes with id from specific values -->
<xsl:template match="TitleReference[StoryPack[key('titleId', @id)/value = $values]]" />
</xsl:stylesheet>
Thank you for your help!
=============
Following @michael.hor257k answers : my source XML is a little more complex, that's probably why it doesn't work in my case: The Xpath of value is deeper: /Pack/titlesPacks/StoryPack/assets/TitleAssets/assets/StringAssetInfo/value So I've done:
<xsl:template match="TitleReference[key('titleId', @id)/assets/TitleAssets/assets/StringAssetInfo[@attrId = '127']/value = $values]" />
but it doesn't work.
XML:
<?xml version="1.0" encoding="UTF-8"?>
<Pack>
<titlesPacks>
<StoryPack id="1111111">
<assets>
<TitleAssets>
<assets>
<StringAssetInfo attrId="127">
<value>A</value>
</StringAssetInfo>
</assets>
</TitleAssets>
</assets>
</StoryPack>
</titlesPacks>
<referenceTable>
<ReferenceTable>
<titlesReferences>
<TitleReference id = "1111111"/>
</titlesReferences>
</ReferenceTable>
</referenceTable>
</pack>
my need is to
StoryPack
where attribute attrId
of StringAssetInfo
= 127 and value
= A, or B... => Already OKTitleReference
where id
attribute value = id
attribute value of deleted nodes aboveTry it this way?
XSLT 2.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="titleId" match="StoryPack" use="@id"/>
<!-- Values for which nodes must be deleted -->
<xsl:variable name="values">
<value>A</value>
<value>B</value>
<value>C</value>
</xsl:variable>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Delete nodes with specific values -->
<xsl:template match="StoryPack[value = $values/value]"/>
<!-- Delete nodes with id from specific values -->
<xsl:template match="TitleReference[key('titleId', @id)/value = $values/value]" />
</xsl:stylesheet>
I have simplified the variable definition, so it can work in this online demo: https://xsltfiddle.liberty-development.net/jz1PuP9 - and also because it's simpler.
In view of your updated XML structure, change:
<xsl:template match="StoryPack[value = $values/value]"/>
to:
<xsl:template match="StoryPack[.//value = $values/value]"/>
or (preferably) to:
<xsl:template match="StoryPack[assets/TitleAssets/assets/StringAssetInfo/value = $values/value]"/>
and change:
<xsl:template match="TitleReference[key('titleId', @id)/value = $values/value]" />
to:
<xsl:template match="TitleReference[key('titleId', @id)//value = $values/value]" />
or (preferably) to:
<xsl:template match="TitleReference[key('titleId', @id)/assets/TitleAssets/assets/StringAssetInfo/value = $values/value]" />