Reputation: 8594
I'm working on an XSLT that will output an XSLT that will be used by our installer to update an installed XML configuration file.
My first XSLT looks like this:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:outxsl="outputsasxsl" exclude-result-prefixes="outxsl">
<xsl:output method="xml" indent="yes" />
<xsl:namespace-alias result-prefix="xsl" stylesheet-prefix="outxsl"/>
<!-- XsltArgumentList parameters-->
<xsl:param name="parameter1">default1</xsl:param>
<xsl:param name="parameter2">default2</xsl:param>
<xsl:param name="parameter3">default3</xsl:param>
<xsl:param name="parameter4">default4</xsl:param>
<xsl:param name="parameter5">default5</xsl:param>
<xsl:param name="parameter6">default6</xsl:param>
<xsl:template match="/">
<outxsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<outxsl:output method="xml" indent="yes" />
<!-- Output all nodes & attributes for all Elements -->
<outxsl:template match="/Element/Elements/Element">
<!-- Copy all attributes and nodes -->
<outxsl:copy-of select="@* | node()" />
<!-- Output the new configuration info -->
<Element xsi:type="MyType">
<Enabled>true</Enabled>
<ID>1A619316-634A-43C0-BE69-97BB7865219F</ID>
<Property1><xsl:value-of select="$parameter1"/></Property1>
<Property2><xsl:value-of select="$parameter2" /></Property2>
<Property3><xsl:value-of select="$parameter3" /></Property3>
<Property4><xsl:value-of select="$parameter4" /></Property4>
<Property5><xsl:value-of select="$parameter5" /></Property5>
</Element>
</outxsl:template>
<!-- Output everything for all the Details -->
<outxsl:template match="/Element/Details/Detail">
<!-- Copy all attributes and nodes -->
<outxsl:copy-of select="@* | node()"/>
<Detail>
<Property1>1A619316-634A-43C0-BE69-97BB7865219F</Property1>
<Property2>aName</Property2>
<Property3><xsl:value-of select="$parameter6"/></Proprty3>
<Property4>anotherName</Property4>
</Detail>
</outxsl:template>
</outxsl:stylesheet>
</xsl:template>
</xsl:stylesheet>
When I run this transform in the VS 2013 XSLT tool, it works and I get a new XSLT that looks like this:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/Element/Elements/Element">
<xsl:copy-of select="@* | node()" />
<Element xsi:type="MyType">
<Enabled>true</Enabled>
<ID>1A619316-634A-43C0-BE69-97BB7865219F</ID>
<Property1>value1</Property1>
<Property2>value2</Property2>
<Property3>value3</Property3>
<Property4>value4</Property4>
<Property5>value5</Property5>
</Element>
</xsl:template>
<xsl:template match="/Element/Details/Detail">
<xsl:copy-of select="@* | node()" />
<Detail>
<Property1>1A619316-634A-43C0-BE69-97BB7865219F</Property1>
<Property2>aName</Property2>
<Property3>Default6</Property3>
<Property4>anotherName</Property4>
</Detail>
</xsl:template>
</xsl:stylesheet>
When I try running this second XSLT, I get the "An item of type 'Attribute' cannot be constructed within a node of type 'Root.'" error. When I try to start the VS2013 XSLT debugger, VS crashes, so I can't even figure out what line the error is occurring on. I've tried commenting out most of code in there and the error still happens, so I think the error is somewhere near the top.
Would someone please help me figure out what's wrong with the second XSLT & how to fix the first one?
EDIT
Here's a sample of the XML that is to be processed by the second XSLT:
<?xml version="1.0" encoding="utf-8"?>
<Element xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="SubElement">
<ID>1f293e9d-e779-4e07-81e8-de13fd8cac7c</ID>
<Enabled>true</Enabled>
<Name>Normal</Name>
<Elements>
<Element xsi:type="Type1">
<ID>07e9b115-f53f-4137-8aeb-73bca17484a6</ID>
<Enabled>true</Enabled>
<Name>Type1</Name>
<Stuff>
<MoreStuff />
</Stuff>
<OtherStuff xsi:type="Type2">
<ID>b50ae9ee-500f-483a-979e-5774de146480</ID>
<Enabled>true</Enabled>
<Name>Type2</Name>
<MoreStuff />
</OtherStuff>
<SomeProperty1>A Value</SomeProperty1>
<SomeProperty2>A Second Value</SomeProperty2>
<SomeProperty3>A Third Value</SomeProperty3>
</Element>
<Element xsi:type="Type3">
<ID>39ced73b-098b-4ec1-8b1f-c62f1b71c3ed</ID>
<Enabled>true</Enabled>
<Name>Type3</Name>
<SiteId>1ced7cfc-54e7-4d7e-858d-40875ff7b99d</SiteId>
<StartLPRsOnStart>false</StartLPRsOnStart>
</Element>
</Elements>
<Details>
<Detail>
<Property1>39ced73b-098b-4ec1-8b1f-c62f1b71c3ed</Property1>
<Property2>PlateRead</Property2>
<Property3>e8a0b04c-4c38-48e5-b013-307dd2876f3a</Property3>
<Property4>ReadIn</Property4>
</Detail>
<Detail>
<Property1>07e9b115-f53f-4137-8aeb-73bca17484a6</Property1>
<Property2>Subscribe</Property2>
<Property3>39ced73b-098b-4ec1-8b1f-c62f1b71c3ed</Property3>
<Property4>ObjectIn</Property4>
</Detail>
<Detail>
<Property1>07e9b115-f53f-4137-8aeb-73bca17484a6</Property1>
<Property2>RPC</Property2>
<Property3>39ced73b-098b-4ec1-8b1f-c62f1b71c3ed</Property3>
<Property4>RPC</Property4>
</Detail>
<Detail>
<Property1>e8a0b04c-4c38-48e5-b013-307dd2876f3a</Property1>
<Property2>ReadOut</Property2>
<Property3>f8fa94ed-5f16-421b-810f-5eb3b1c0642e</Property3>
<Property4>ReadIn</Property4>
</Detail>
<Detail>
<Property1>f8fa94ed-5f16-421b-810f-5eb3b1c0642e</Property1>
<Property2>ReadOut</Property2>
<Property3>07e9b115-f53f-4137-8aeb-73bca17484a6</Property3>
<Property4>Publish</Property4>
</Detail>
<Detail>
<Property1>07e9b115-f53f-4137-8aeb-73bca17484a6</Property1>
<Property2>Subscribe</Property2>
<Property3>f8fa94ed-5f16-421b-810f-5eb3b1c0642e</Property3>
<Property4>ObjectIn</Property4>
</Detail>
<Detail>
<Property1>f8fa94ed-5f16-421b-810f-5eb3b1c0642e</Property1>
<Property2>AlarmOut</Property2>
<Property3>07e9b115-f53f-4137-8aeb-73bca17484a6</Property3>
<Property4>Publish</Property4>
</Detail>
<Detail>
<Property1>e253bfb5-4795-4d40-b4ff-88a334a17fc6</Property1>
<Property2>LogEvent</Property2>
<Property3>07e9b115-f53f-4137-8aeb-73bca17484a6</Property3>
<Property4>Publish</Property4>
</Detail>
<Detail>
<Property1>1efde71d-9763-418e-be6d-984fce13869f</Property1>
<Property2>RunHotlist</Property2>
<Property3>5e6dcf8d-60be-4aab-b26c-91ca988bb821</Property3>
<Property4>RunHotlist</Property4>
</Detail>
<Detail>
<Property1>1efde71d-9763-418e-be6d-984fce13869f</Property1>
<Property2>TaskOut</Property2>
<Property3>07e9b115-f53f-4137-8aeb-73bca17484a6</Property3>
<Property4>Publish</Property4>
</Detail>
</Details>
</Element>
Upvotes: 0
Views: 2060
Reputation: 116982
First and foremost, note that your (second) XSLT produces an XML without a root element - which is no XML at all.
Now, AFAICT the problematic part is here:
<xsl:template match="/Element/Elements/Element">
<xsl:copy-of select="@* | node()" />
You are matching an element with attributes, but you are not creating a corresponding output element. So the instruction to copy @*
cannot be performed, because there is no element to "carry" the copied attributes.
Upvotes: 1