Preparing XSD of a complex xml - c#

Thank you all for suggesting things and helping whenever in need.
Yesterday I was trying to develop and web app in asp.net 4.0 where I needed to parse the data from xml and save it in database. But before that I will also have to validate it.
I tried using .net provided tool xsd.exe to generate the schema file, but I dont know how will it know to mark which nodes or attributes are compulsory?
Like in my xml below items are mandatory
Root node <Market>
<Login> and its sub element
<ProductType> and its <ProductTypeID/>
The attribute DML is mandatory but should have only 3 values NONE, PUT or MODIFY
<ProductType> may or may not have <ProductItem>
If <ProductItem> is present then it should have <ProductItemID>
<ProductItem> may or may not have <Brand>
If <Brand> is present then it should have <BrandID>
Below is my xml
<?xml version="1.0" encoding="utf-8" ?>
<Market>
<Login>
<LoginId />
<Password />
</Login>
<ProductType DML="NONE">
<ProductTypeID/>
<Name/>
<Detail/>
<ProductItem DML="PUT">
<ProductItemID/>
<Name/>
<Detail/>
<Brand DML="PUT">
<BrandID/>
<Name/>
<Detail/>
</Brand>
<Brand DML="MODIFY">
<BrandID/>
<Name/>
<Detail/>
</Brand>
</ProductItem>
<ProductItem DML="MODIFY">
<ProductItemID/>
<Name/>
<Detail/>
</ProductItem>
</ProductType>
</Market>
How and where should I specify all the mandatory and optional parameters, so that my xsd is generated as per the requirement.
Thanks,
M.

xsd.exe can only try to infer, which elements/attributes are in you xml, but it cannot find out which information is mandatory. But this is a good startingpoint.
use a graphical XML_Schema_Editor to edit the genrated xsd to mark your mandatory fields. That is much easier than learning the xsd-language

I don't think XSD support nested XML. I would try to load the XML into an XmlDocument and check mandatory fields manually.

Related

How to set I/O values in siemens PLC Device?

I am creating a Web API for a local network in the .net framework(C#). In that user can import/export IO Tags from excel or set them as a static string array. I have added (Siemens.Engineering.Hmi.dll) but still, it shows a not found compile-time error.
We have also connected to TIAPortal and it works well the only roadblocks are I/O tags import/export or set static values and HMISoftware.
Project: Web API(.Net Framework 4.6.1)
Tia Portal: v16.0
License Type: Trial
Kindly revert me if anyone have idea or any suggestion. It would be highly appriciated.
The issue you are experiencing is that (most probably) you didn't set the copy local property of the referenced Siemens.Engineering.Hmi.dll to false. So, the dependencies of the referenced Siemens.Engineering.Hmi.dll cannot be found. As a remark: add the Siemens.Engineering.dll as a reference besides Siemens.Engineering.Hmi.dll
Having a not-local-assembly then requires AssemblyResolving. The simplest way of doing it is to use the App.config file.
Please see this page from Siemens about this topic:
support.industry.siemens.com
The second issue I see is the access of Tags. As you most certainly know, there are HMI Tags and PLC Tags. Accessing them is possible through the respective DeviceItems. These DeviceItems expose different Services. You can access the Services through the <YourEngineeringObject>.GetService<T>() method. In this case you will need the SoftwareContainer service.
To become familiar with the data model of TIA Openness, please have a look at the TIA Openness Explorer
Also, to deepen your understanding of working with TIA Openness, please refer to SIMATIC TIA Portal Openness: API for automation of engineering workflows
The solution I'm importing IO tags is to use .xml files
Its advantage is that it can access and set the properties of IO tags, such as IO tagstable's name, datatypename, externalaccessible, externalvisible, externalwritable, logicaladdress, tagName, comment.
For Example .xml
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V16" />
<SW.Tags.PlcTagTable ID="0">
<AttributeList>
<Name>IO Table</Name>
</AttributeList>
<ObjectList>
<SW.Tags.PlcTag ID="1" CompositionName="Tags">
<AttributeList>
<DataTypeName>Bool</DataTypeName>
<ExternalAccessible>true</ExternalAccessible>
<ExternalVisible>true</ExternalVisible>
<ExternalWritable>true</ExternalWritable>
<LogicalAddress>%I0.0</LogicalAddress>
<Name>Tag</Name>
</AttributeList>
<ObjectList>
<MultilingualText ID="2" CompositionName="Comment">
<ObjectList>
<MultilingualTextItem ID="3" CompositionName="Items">
<AttributeList>
<Culture>en-US</Culture>
<Text>Tag</Text>
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Tags.PlcTag>
</ObjectList>
</SW.Tags.PlcTagTable>
</Document>
You only need to modify the tags attribute in. XML, including the ID value. For example, first tag ID = 1, and the second tag ID = 2.ID's value is not repeatable!
For Example .cs
var fileInfo = new FileInfo(#"IO MAP.xml");
SoftwareContainer softwareContainer = Project.Devices[0].DeviceItems[1].GetService<SoftwareContainer>();
Software softwareBase = softwareContainer.Software;
PlcSoftware plcSoftware = softwareBase as PlcSoftware;
PlcTagTableGroup PlcTagTableGroup = plcSoftware.TagTableGroup;
PlcTagTableGroup.TagTables.Import(fileInfo, ImportOptions.Override);
You only need to modify the target of SoftwareContainer , which depends on the PLC model you use, in the case of s7-1516.
If you have any questions, please contact me。

Creating XML Banking document from template

I have this template from a bank that is used to make payments on bank account transfers.
See xml below. I have included the sample data that has to be entered when sending the file to the bank.
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<CstmrCdtTrfInitn>
<GrpHdr>
<MsgId>Cart Urgent28052018_57894</MsgId>
<CreDtTm>2018-06-29T11:52:23</CreDtTm>
<NbOfTxs>1</NbOfTxs>
<CtrlSum>667896.00</CtrlSum>
<InitgPty>
<Nm>CART LIMITED</Nm>
<Id>
<OrgId>
<Othr>
<Id>S001234/PJones</Id>
<SchmeNm>
<Cd>CUST</Cd>
</SchmeNm>
</Othr>
</OrgId>
</Id>
</InitgPty>
</GrpHdr>
<PmtInf>
<PmtInfId>Payment for addon development SAP B1</PmtInfId>
<PmtMtd>TRF</PmtMtd>
<BtchBookg>false</BtchBookg>
<NbOfTxs>1</NbOfTxs>
<CtrlSum>667896.00</CtrlSum>
<PmtTpInf>
<InstrPrty>HIGH</InstrPrty>
</PmtTpInf>
<ReqdExctnDt>2018-06-29</ReqdExctnDt>
<Dbtr>
<Nm>CART LIMITED</Nm>
</Dbtr>
<DbtrAcct>
<Id>
<Othr>
<Id>0112345110846</Id>
</Othr>
</Id>
<Ccy>KES</Ccy>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BIC>SBICKENX</BIC>
</FinInstnId>
</DbtrAgt>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>156335578965</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="KES">667896.00</InstdAmt>
</Amt>
<ChrgBr>DEBT</ChrgBr>
<CdtrAgt>
<FinInstnId>
<BIC>DTKEKENA</BIC>
<ClrSysMmbId>
<MmbId>63000</MmbId>
</ClrSysMmbId>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>EOH SEAL LTD</Nm>
<PstlAdr>
<StrtNm>P.O. Box 10496</StrtNm>
<TwnNm>Nairobi</TwnNm>
<Ctry>KE</Ctry>
<AdrLine>P.O. Box 10496</AdrLine>
<AdrLine>00100 NAIROBI</AdrLine>
</PstlAdr>
</Cdtr>
<CdtrAcct>
<Id>
<Othr>
<Id>0112406001</Id>
</Othr>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>Cart Urgent28052018_57894</Ustrd>
</RmtInf>
</CdtTrfTxInf>
</PmtInf>
</CstmrCdtTrfInitn>
</Document>
The file is quite long as has to be in the format given. The black letters represent the details to be passed to the xml. To test if I understood what data goes where I filled it manually and sent to bank for testing. That is all good now.
I have a SAP addon program that captures details from a form and generates a list. Each payment must follow this structure.
Looking at the below:
<Nm>CART LIMITED</Nm>
<Id>
<OrgId>
<Othr>
<Id>S001234/PJones</Id>
<SchmeNm>
<Cd>CUST</Cd>
</SchmeNm>
</Othr>
</OrgId>
</Id>
Is creating a class with all properties according to the template the best way to create the xml needed.
How do I stagger the
<Id>
<OrgId>
<Othr>
as in the case above?
Also the <CtrlSum>667896.00</CtrlSum> is found in the group header and payment info tags. How do I deal with this?
For what i see, the problem is you have a addon in SAP to specify multiple payments methods, but in the XML template given from the bank you don't the structure for multiple payments, so you need to get this information to know how can you work with it.
when you have this information you can use a better XML template with VS or another tool to generate the correct class to work with the XML

how to delete root tag in xml C#

hi following XML is my input XML
<?xml version="1.0" encoding="utf-8"?>
<units xmlns="http://www.elsevier.com/xml/ani/ani" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ce="http://www.elsevier.com/xml/ani/common" xsi:schemaLocation="http://www.elsevier.com/xml/ani/ani http://www.elsevier.com/xml/ani/ani512-input-CAR.xsd">
<unit type="journal" xmlns="">
<unit-info>
<timestamp>2017-01-08T02:03:14Z</timestamp>
<order-id>12535892</order-id>
<parcel-id>none</parcel-id>
<unit-id>4756202</unit-id>
</unit-info>
<unit-content>
<bibrecord>
<item-info>
<status state="new" stage="S300" />
</item-info>
<head>
<citation-info>
<citation-type code="jo" />
<citation-language xmllang="ENG" />
<abstract-language xmllang="ENG" />
<author-keywords>
<author-keyword>Stroke</author-keyword>
<author-keyword> cerebral ischaemia</author-keyword>
<author-keyword> Neuro-protection</author-keyword>
<author-keyword> Neuro-protective agents</author-keyword>
</author-keywords>
</citation-info>
<citation-title xmllang="ENG" original="y">
<titletext>PATHOGENESIS AND NEURO-PROTECTIVE AGENTS OF STROKE</titletext>
</citation-title>
<abstracts>
<abstract>
<cepara>ABSTRACT: Stroke remains worlds second leading cause of mortality; and globally most frequent cause of long-lasting disabilities. The ischaemic pathophysiologic cascade leading to neuronal damage consists of peri-infarct depolarization, excitotoxicity, inflammation, oxidative stress, and apoptosis. Despite plethora of experimental evidences and advancement into the development of treatments, clinical treatment of acute stroke still remains challenging. Neuro-protective agents, as novel therapeutic strategy confer neuro-protection by targeting the pathophysiologic mechanism of stroke. The aim of this review is discussion of summary of the literature on stroke pathophysiology, current preclinical research findings of neuroprotective agents in stroke and possible factors that were responsible for the failure of these agents to translate in human stroke therapies.</cepara>
</abstract>
</abstracts>
<correspondence>
<person>
<ceinitials>M.</ceinitials>
<cesurname>Mubarak</cesurname>
</person>
<affiliation>
<organization> Bayero University Kano</organization>
<organization> Nigeria. Email: mubarakmahmad#yahoo.com</organization>
</affiliation>
</correspondence>
<root>
<author Seq="0">
<Inital>A.El</Inital>
<Surname>Khattabi</Surname>
<Givenname>Abdelkrim</Givenname>
</author>
</root>
</head>
</bibrecord>
</unit-content>
from this xml i need to delete root tag alone but i need all child element
<author Seq="0">
<Inital>A.El</Inital>
<Surname>Khattabi</Surname>
<Givenname>Abdelkrim</Givenname>
</author>
how to delete root tag alone. For this i followed following code
XDocument CarXML = new XDocument();
CarXML.Add(Root);
CarXML.Descendants("root").Remove();
CarXML.Save(#"CAR.XML");
But this code delete all xml tag. How to delete root element alone. i need child element
CarXML.ReplaceNodes(CarXML.Descendants("author").FirstOrDefault());
This replaces the whole content of the XML with the first descendant named author.

What is wrong with this file or code?

What is happening \ what is the difference ?
I'm trying to return a specific node from an XML File.
XML File:
<?xml version="1.0" encoding="utf-8"?>
<JMF SenderID="InkZone-Controller" Version="1.2">
<Command ID="cmd.00695" Type="Resource">
<ResourceCMDParams ResourceName="InkZoneProfile" JobID="K_41">
<InkZoneProfile ID="r0013" Class="Parameter" Locked="false" Status="Available" PartIDKeys="SignatureName SheetName Side Separation" DescriptiveName="Schieberwerte von DI" ZoneWidth="32">
<InkZoneProfile SignatureName="SIG1">
<InkZoneProfile Locked="False" SheetName="S1">
<InkZoneProfile Side="Front" />
</InkZoneProfile>
</InkZoneProfile>
</InkZoneProfile>
</ResourceCMDParams>
</Command>
<InkZoneProfile Separation="Cyan" ZoneSettingsX="0 0,005 " />
</JMF>
Code:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("C:\\test\\test.xml");
XmlNode root = xmlDoc.DocumentElement;
var parent = root.SelectSingleNode("/JMF/Command/ResourceCmdParams/InkZoneProfile/InkZoneProfile/InkZoneProfile/InkZoneProfile");
XmlElement IZP = xmlDoc.CreateElement("InkZoneProfile");
IZP.SetAttribute("Separation", x.colorname);
IZP.SetAttribute("ZoneSettingsX", x.colorvalues);
xmlDoc.DocumentElement.AppendChild(IZP);
xmlDoc.Save("C:\\test\\test.xml");
The var parent returns me null. I've debugged , and root and xmlDoc have on their inner text the XML Content.
But, a test made here(made by user #har07 , on the previous question:
SelectSingleNode returns null even with namespace managing
Worked without problems.
https://dotnetfiddle.net/vJ8h9S
What is the difference between those two ? They follow the same code basically, but one works and other doesn't.
When debugging i've found that root.InnerXml has the contents loaded on itself (same as XmlDoc.InnerXml ). But InnerXml doesn't implement a method to SelectSingleNode. I believe that if i save it to a string i'll probably lose indentation and etc.
Can someone tell me what is the difference or what is wrong ? Thanks !
XML Sample: https://drive.google.com/file/d/0BwU9_GrFRYrTUFhMYWk5blhhZWM/view?usp=sharing
SetAttribute don't auto escape string for you. Therefore it make your XML file invalid.
From MSDN about XmlElement.SetAttribute
Any markup, such as syntax to be recognized as an entity reference, is treated as literal text and needs to be properly escaped by the implementation when it is written out
Find in your code all line contain SetAttribute and use SecurityElement.Escape to escape the value.
For example: Change these lines:
IZP.SetAttribute("Separation", x.colorname);
IZP.SetAttribute("ZoneSettingsX", x.colorvalues);
To:
using System.Security;
IZP.SetAttribute("Separation", SecurityElement.Escape(x.colorname));
IZP.SetAttribute("ZoneSettingsX", SecurityElement.Escape(x.colorvalues));
If an attribute have name contains any of <>"'& you also have to escape it like the value.
Note:
You have to delete current xmls you create used the old code, because it is invalid, when you load it will cause exception.

Pivotviewer's .cxml parsing

I'm trying to do very simple operations on a .cxml file. As you know it's basically an .xml file. This is a sample file I created to test the application:
<?xml version="1.0" encoding="utf-8"?>
<Collection xmlns:p="http://schemas.microsoft.com/livelabs/pivot/collection/2009" SchemaVersion="1.0" Name="Actresses" xmlns="http://schemas.microsoft.com/collection/metadata/2009">
<FacetCategories>
<FacetCategory Name="Nationality" Type="LongString" p:IsFilterVisible="true" p:IsWordWheelVisible="true" p:IsMetaDataVisible="true" />
</FacetCategories>
<!-- Other entries-->
<Items ImgBase="Actresses_files\go144bwo.0ao.xml" HrefBase="http://www.imdb.com/name/">
<Item Id="2" Img="#2" Name="Anna Karina" Href="nm0439344/">
<Description> She is a nice girl</Description>
<Facets>
<Facet Name="Nationality">
<LongString Value="Danish" />
</Facet>
</Facets>
</Item>
</Items>
<!-- Other entries-->
</Collection>
I can't get any functioning simple code like:
XDocument document = XDocument.Parse(e.Result);
foreach (XElement x in document.Descendants("Item"))
{
...
}
The test on a generic xml is working. The cxml file is correctly loaded in document.
While watching the expression:
document.Descendants("Item"), results
the answer is:
Empty "Enumeration yielded no results" string
Any hint on what can be the error? I've also add a quick look to get Descendants of Facet, Facets, etc., but there are no results in the enumeration. This obviously doesn't happen with a generic xml file I used for testing. It's a problem I have with .cxml.
Basically your XML defines a default namespace with the xmlns="http://schemas.microsoft.com/collection/metadata/2009" attribute:
That means you need to fully qualify your Descendants query e.g.:
XDocument document = XDocument.Parse(e.Result);
foreach (XElement x in document.Descendants("{http://schemas.microsoft.com/collection/metadata/2009}Item"))
{
...
}
If you remove the default namespace from the XML your code actually works as-is, but that is not the aim of the exercise.
See Metadata.CXML project under http://github.com/Zoomicon/Metadata.CXML sourcecode for LINQ-based parsing of CXML files.
Also see ClipFlair.Metadata project at http://github.com/Zoomicon/ClipFlair.Metadata for parsing one's CXML custom facets too
BTW, at http://ClipFlair.codeplex.com can checkout the ClipFlair.Gallery project for how to author ASP.net web-based forms to edit metadata fragments (parts of CXML files) and merge them together in a single one (that you then convert periodically to DeepZoom CXML with PAuthor tool from http://pauthor.codeplex.com).
If anyone is interested in doing nesting (hierarchy) of CXML collections see
http://github.com/Zoomicon/Trafilm.Metadata
and
http://github.com/Zoomicon/Trafilm.Gallery

Categories

Resources