When I digitally sign an XML file with RSA it works perfectly, as long as the Reference URI is not numbers, and I need to sign the XML portion with a purely numeric ID.
I have 2 weeks of research and I can't find the way around.
This work perfectly
<book id="abc123">
<title>Programming .NET Security</title>
<author>Adam Freeman</author>
<author>Allen Jones</author>
</book>
reference = New Reference
reference.Uri = "#abc123"
This does not work, malformed reference element
<book id="12345">
<title>Programming .NET Security</title>
<author>Adam Freeman</author>
<author>Allen Jones</author>
</book>
reference = New Reference
reference.Uri = "#12345"
When the URI Reference is only numbers it doesn't work for me, if it has letters it works, I've tried it in C# and in VB.Net
Framework 3 to 4
Windows 10
Windows 2012 Server
Windows 2008
Related
I am generating an XML file that I am sending to another system. The XML file generates correctly however the secondary system requires specific headers to deserialize correctly.
I am struggling with the XML tags and how to structure my classes that insert the data.
PostShipmentNotesBD -> ShipmentNoteBD -> Shipmentheader -> ShipmentDetailsBD -> MerchandiseLineBD
[XmlType("PostShipmentNotes")] -> [XmlType("ShipmentNote")] -> [XmlType("ShipmentHeader")] -> [XmlType("ShipmentDetails")] -> [XmlType("MerchandiseLine")]
For whatever reason the PostShipmentNotes and MerchandiseLines use the XMLType as the header but the rest do not? I have played around with roots, elements and more but I am a bit out of my area of knowledge and just looking for the right direction.
<?xml version="1.0" encoding="utf-8"?>
<PostShipmentNotes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ShipmentNoteBD>
<ShipmentHeader>
<CustomerName>Some Company</CustomerName>
<ShipmentStatusPrinted>Y</ShipmentStatusPrinted>
<ShipCode>1010</ShipCode>
<PlannedShipmentDate>2021-11-10</PlannedShipmentDate>
<SalesOrder>666777</SalesOrder>
<ShipAddress1>Big Long Street Name</ShipAddress1>
<ShipAddress2> </ShipAddress2>
</ShipmentHeader>
<ShipmentDetailsBD>
<MerchandiseLine>
<SalesOrderLine>1</SalesOrderLine>
<ShipmentQty>21</ShipmentQty>
<OverOrUnderShipment>N</OverOrUnderShipment>
</MerchandiseLine>
</ShipmentDetailsBD>
</ShipmentNoteBD>
</PostShipmentNotes>
I am programming in C#. I was previously using the following command line to convert an xml with a xsl and output it as a html.
java -jar "C:\Data\saxon-he-9.4.0.7.jar" View.xml Stylesheet.xsl -o:output.html
However, I am now trying to use the Saxon .Net API to do the same process using the following code:
var xslt = new FileInfo(#"C:\\Data\\Stylesheet.xsl");
var input = new FileInfo(#"C:\\Data\\View.xml");
var output = new FileInfo(#"C:\\Data\\test.html");
// Compile stylesheet
var processor = new Processor();
var compiler = processor.NewXsltCompiler();
var executable = compiler.Compile(new Uri(xslt.FullName));
// Do transformation to a destination
var destination = new DomDestination();
using (var inputStream = input.OpenRead())
{
var transformer = executable.Load();
transformer.SetInputStream(inputStream, new Uri(input.DirectoryName));
transformer.Run(destination);
}
// Save result to a file (or whatever else you wanna do)
destination.XmlDocument.Save(output.FullName);
However I recieve the error:
"An unhandled exception of type 'Saxon.Api.DynamicError' occurred in saxon9he-api.dll"
When running the line "transformer.Run(destination);"
The following screenshots are from the Visual Studio's Locals Debugging:
$exception {"XSLT 1.0 compatibility mode is not available in this configuration"} Saxon.Api.DynamicError
transformer {Saxon.Api.XsltTransformer} Saxon.Api.XsltTransformer
The first thing you need to do is to get more specific information about the nature of the error. Catching the exception and printing the exception message would be a good start. But Saxon will have written diagnostics to the standard error output, which probably ends up in some log file somewhere, depending on how your application is configured and run. If you can't track it down, try redirecting it as described here: How to capture a Processes STDOUT and STDERR line by line as they occur, during process operation. (C#)
Once you've established the actual error, edit the question and we can start investigating what's wrong if it's not obvious.
A common cause of problems when writing to a DomDestination is that your result tree isn't well-formed, e.g, it has text nodes or multiple elements at the top level. It's not clear why you are writing to a DomDestination - if you just want to produce serialized XML, then write to a Serializer.
LATER
Now you've found the error message ("XSLT 1.0 compatibility mode is not available in this configuration") it should be fairly clear. When a stylesheet specifies version="1.0" and is run with an XSLT 2.0 or 3.0 processor, it runs in a compatibility mode where certain things behave differently (for example xsl:value-of ignores all but the first selected item). This compatibility mode, from Saxon 9.8 onwards, is not available in Saxon-HE. You need to do one of three things: upgrade to Saxon-PE or -EE; revert to an earlier Saxon-HE version; or convert your stylesheet to XSLT 2.0 (which basically means (i) change the value of the version attribute (ii) test that it still works.)
I'm trying to sign a XML document with a reference to the KeyInfo node but I'm getting "malformed reference element" exception after calling the method "ComputeSignature".
This is my code:
signedXml.SigningKey = certificate.PrivateKey;
if (!signParameters.IncludeCertificateInSignature) return;
var certificateKeyInfo = new KeyInfo();
certificateKeyInfo.AddClause(new KeyInfoX509Data(certificate));
signedXml.KeyInfo = certificateKeyInfo;
signedXml.KeyInfo.Id = "xmldsig-keyinfo";
signedXml.AddReference(new Reference("#xmldsig-keyinfo"));
If I remove the "#xmldsig-keyinfo", it works, but I get the reference with the entire document, I need the reference with the KeyInfo tag.
I finally found the answer, I can't add the KeyInfoId reference because the xmlElement is not created yet in the XMLDoc; so I implemented the SigneXML class and return the XML directly from the keyInfo.
public override XmlElement GetIdElement(XmlDocument doc, string id)
{
if (String.Compare(id, this.KeyInfo.Id, StringComparison.OrdinalIgnoreCase) == 0)
return this.KeyInfo.GetXml();
else
return base.GetIdElement(doc, id);
}
I hope it helps!!
In my case, after days trapped. It was the Reference.uri. I was saving it as "# 1". The XML was.
<getTest>
<item ID="1">
<Seed>123</Seed>
</item>
</getTest>
that worked ok on Windows Server 2003 but failed on developer machine on Windows 10 and Windows Server 2012 R2 server. It was falling into ComputeSignature method.
Finally I read that the ID cannot be a number, if it must start with a letter.
https://www.w3.org/TR/html401/types.html#type-name
I changed it to test
reference.uri = "#test" and the base XML I changed how show below.
<getTest>
<item ID="test">
<Seed>123</Seed>
</item>
</getTest>
and voila, it works in all environments.
There are some patches in the S.O. new ones that cause it to fail and not work in the old ones that did not have these patches and that are the ones that place that restriction.
KB3140745
KB3140768
KB3140743
KB3073930
I'm trying to change the pitch of spoken text via SSML and the .NET SpeechSynthesizer (System.Speech.Synthesis)
SpeechSynthesizer synthesizer = new SpeechSynthesizer();
PromptBuilder builder = new PromptBuilder();
builder.AppendSsml(#"C:\Users\me\Documents\ssml1.xml");
synthesizer.Speak(builder);
The content of the ssml1.xml file is:
<?xml version="1.0" encoding="ISO-8859-1"?>
<ssml:speak version="1.0"
xmlns:ssml="http://www.w3.org/2001/10/synthesis"
xml:lang="en-US">
<ssml:sentence>
Your order for <ssml:prosody pitch="+30%" rate="-90%" >8 books</ssml:prosody>
will be shipped tomorrow.
</ssml:sentence>
</ssml:speak>
The rate is recognized: "8 books" is speaken much slower than the rest, but no matter what value is set for "pitch", it makes no difference ! Allowed values can be found here:
http://www.w3.org/TR/speech-synthesis/#S3.2.4
Am I missing something or is changing the pitch just not supported by the Microsoft Speech engine ?
fritz
While the engine SsmlParser used by System.Speech accepts a pitch attribute in the ProcessProsody method, it does not process it.
It only processes the range, rate, volume and duration attributes. It also parses contour but is processed as range (not sure why)...
Edit: if you don't really need to read the text from a SSML xml file, you can create the text programatically.
Instead of
builder.AppendSsml(#"C:\Users\me\Documents\ssml1.xml");
use
builder.Culture = CultureInfo.CreateSpecificCulture("en-US");
builder.StartVoice(builder.Culture);
builder.StartSentence();
builder.AppendText("Your order for ");
builder.StartStyle(new PromptStyle() { Emphasis = PromptEmphasis.Strong, Rate = PromptRate.ExtraSlow });
builder.AppendText("8 books");
builder.EndStyle();
builder.AppendText(" will be shipped tomorrow.");
builder.EndSentence();
builder.EndVoice();
I’m after some C# code that will have the following methods that will return Xml as the result.
Search the Apple iTunes App store. If I pass it a name or partial name the function must return a list of possible search results or just one result if it is a perfect match.
Example shown below:
<App>
<AppId>321564880</AppId>
<Name>Doodle Clock - Clock A Doodle Do!</Name>
<ReleaseDate>Released Sep 28, 2009</ReleaseDate>
<Artist>YARG</Artist>
<Description>Description of App</Description>
<Copyright>© YARG Limited 2009</Copyright>
<Price>$0.99</Price>
<Category>Lifestyle</Category>
<MainImageUrl><!—main App icon image urlà </ImageUrl>
<ExtraImages>
<!-- these will be the extra images you see in the App store other than the main application icon -->
<ImageUrl> <!—url of extra image 1à</ImageUrl>
<ImageUrl> <!—url of extra image 2à</ImageUrl>
<ImageUrl> <!—url of extra image 3à</ImageUrl>
</ExtraImages>
<Version>Version: 1.1 (iPhone OS 3.0 Tested)</Version>
<Size>1.5 MB</Size>
</App>
Okay the best way to create xml file and parse and manipulate them is using XDocument,XElement,etc. Because they are enumerable which means you can use LINQ on them and that will help you a lot.
For example :
XElement element = new XElement("Persons",
new XElement("Person","John",
new XAttribute("Id","1")),
new XElement("Person","Aaron",
new XAttribute("Id",2))
)
returns
<Persons>
<Person Id="1">John</Person>
<Person Id="2">Aaron</Person>
</Person>
More information : System.Xml.Linq Namespace
If you are looking for speed, then you can use XMLReader and XMLWriter but you can't find the flexibility that System.Xml.Linq provides.
You should use XPath in .NET:
http://www.aspfree.com/c/a/.NET/Working-with-XPath-The-NET-Way/
I would use XmlTextReader. It's the fastest way (though read-forward-only) - if you are maybe looking for speed. If not, XPath should do.