go-xml
go-xml copied to clipboard
Referenced node has no explicit xmlns namespace when marshalling
Hi, I am trying to include the external xmldsig schema into my schema and to generate the structs. This steps works and this is great! In the next step I use xmlsec1 to sign the marshalled XML but then it complains that it can't find the Signature node.
Error: failed to find default node with name="Signature"
It seems that xmlsec1 expects that the marshalled XML contains a Signaute node with its explicit xmlns namespace/
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
When I am marshalling the XML I get a Signature node without its namespace but all its child nodes contain it. Is it somehow possible to achieve that the Signature node also has its namespace explicitly when marshalled?
Result:
<MetaDataType>
<Signature>
<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<CanonicalizationMethod xmlns="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod xmlns="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference xmlns="http://www.w3.org/2000/09/xmldsig#">
<DigestMethod xmlns="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue xmlns="http://www.w3.org/2000/09/xmldsig#"/>
</Reference>
</SignedInfo>
<SignatureValue xmlns="http://www.w3.org/2000/09/xmldsig#"/>
</Signature>
</MetaDataType>
Schema:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
elementFormDefault="qualified">
<xs:import namespace="http://www.w3.org/2000/09/xmldsig#"
schemaLocation="xmldsig-core-schema.xsd" />
<xs:element name="MetaData" type="MetaDataType" />
<xs:complexType name="MetaDataType">
<xs:sequence>
<xs:element ref="ds:Signature"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Generated code:
type MetaDataType struct {
Signature *SignatureType `xml:" Signature"`
}
type SignatureType struct {
SignedInfo *SignedInfoType `xml:"http://www.w3.org/2000/09/xmldsig# SignedInfo"`
SignatureValue *SignatureValueType `xml:"http://www.w3.org/2000/09/xmldsig# SignatureValue"`
KeyInfo *KeyInfoType `xml:"http://www.w3.org/2000/09/xmldsig# KeyInfo,omitempty"`
Object []ObjectType `xml:"http://www.w3.org/2000/09/xmldsig# Object,omitempty"`
Id string `xml:"Id,attr,omitempty"`
}
Thanks for the report.
The problem appears to be that the root element, regardless of what it is, doesn't get a namespace. This could be fixed in the code generation by adding an XMLName
field. In your example, we'd generate something like
type SignatureType struct {
XMLName xml.Name `xml:"http://www.w3.org/2000/09/xmldsig# Signature"`
SignedInfo *SignedInfoType `xml:"http://www.w3.org/2000/09/xmldsig# SignedInfo"`
SignatureValue *SignatureValueType `xml:"http://www.w3.org/2000/09/xmldsig# SignatureValue"`
KeyInfo *KeyInfoType `xml:"http://www.w3.org/2000/09/xmldsig# KeyInfo,omitempty"`
Object []ObjectType `xml:"http://www.w3.org/2000/09/xmldsig# Object,omitempty"`
Id string `xml:"Id,attr,omitempty"`
}
Actually, looking at this closer, the fact that the Signature
field in MetaDataType
does not have a namespace seems like a bug.
I recall a previous issue where the code failed to preserve namespaces when importing types across namespace boundaries (as your schema does), but I thought I fixed that. The fact that this schema does not declare a targetNamespace
may be relevant -- can you try adding a targetNamespace
declaration (the value doesn't matter) to the schema
element and try codegen again?
Thanks for the fast respone. So I changed the schema to
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:ex="urn:example"
targetNamespace="urn:example"
elementFormDefault="qualified">
<xs:import namespace="http://www.w3.org/2000/09/xmldsig#"
schemaLocation="xmldsig-core-schema.xsd" />
<xs:element name="MetaData" type="ex:MetaDataType" />
<xs:complexType name="MetaDataType">
<xs:sequence>
<xs:element ref="ds:Signature"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
and adjusted the namespace flag to
xsdgen -pkg=main -o=xsd/test.go -ns "urn:example" xsd/test.xsd xsd/xmldsig-core-schema.xsd
and in this case it seems to use the target namespace but in my case I would expect that Signautre would have the namespace of xmldsig?
type MetaDataType struct {
Signature *SignatureType `xml:"urn:example Signature"`
}
type SignatureType struct {
SignedInfo *SignedInfoType `xml:"http://www.w3.org/2000/09/xmldsig# SignedInfo"`
SignatureValue *SignatureValueType `xml:"http://www.w3.org/2000/09/xmldsig# SignatureValue"`
KeyInfo *KeyInfoType `xml:"http://www.w3.org/2000/09/xmldsig# KeyInfo,omitempty"`
Object []ObjectType `xml:"http://www.w3.org/2000/09/xmldsig# Object,omitempty"`
Id string `xml:"Id,attr,omitempty"`
}
the xml output is now
<Signature xmlns="urn:example">
Did I do something wrong? I am not sure if this was what you thought about. I am not really an expert in XSD schemas... sorry.
What I forgot to mention is that I am using the omitempty-structs branch but I merged the latest master into it. I also tried it with the master with the same result.
It looks like setting the targetNamespace did not fix the issue and this is a variation of #65 ; elements in another namespace mistakenly get labelled with the targetNamespace of the schema containing the reference.