вставить xsi: schemaLocation и xlmns и префикс в XML

#c# #xml #xml-namespaces

#c# #xml #xml-пространства имен

Вопрос:

Я пытаюсь вставить данные xsi и xsmln в XML, я использовал различные способы, но не смог их получить, мне также нужно вставить префиксы. Далее я показываю свой код, в котором я получаю XML, а также показываю структуру, которую я получаю, и в конце я показываю вам, что я действительно хочу получить. Это код, в котором я получаю XML:

 string txtXML = XmlfrommyfunctionSQL();    // here retrieve from sqlserver          
            XDocument doc;
            using (StringReader s = new StringReader(txtXML))
            {
                doc = XDocument.Load(s);
            }
            doc.Declaration = new XDeclaration("1.0", "UTF-8", null);
            string targetxml = doc.ToString();
            targetxml = doc.Declaration.ToString()   Environment.NewLine   doc.ToString();
  

Это XML, который я получаю в string targetxml:

      <?xml version="1.0" encoding="UTF-8"?>
<Invoice>
    <UBLxtensions>
        <UBLExtension>
            <AccountingSupplierParty>
                <AdditionalAccountID>1</AdditionalAccountID>
                <Party>
                    <PartyName>
                        <Name>GRUPO ERB</Name>
                    </PartyName>
                    <PhysicalLocation>
                        <Address>
                            <ID>11001</ID>
                            <Country>
                                <IdentificationCode>CO</IdentificationCode>
                            </Country>
                        </Address>
                    </PhysicalLocation>
                </Party>
            </AccountingSupplierParty>
        </UBLExtension>
    </UBLExtensions>
</Invoice>

       
  

Но мне нужно вставить xsi:schemaLocation и xmlns и вставить префикс в элементы, как мне это сделать?
Я ожидаю получить это:

 <?xml version="1.0" encoding="UTF-8"?>
<Invoice Invoice xsi:schemaLocation="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 
    http://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/maindoc/UBL-Invoice-2.1.xsd" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#" 
    xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" 
    xmlns:sts="http://www.dianees.com/contra/acturaeca/v1/Structures" 
    xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" 
    xmlns:ds="http://www.w3.org/2000/09/xmldsig#" 
    xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" 
    xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2">
    <ext:UBLExtensions>
        <ext:UBLExtension>
            <cac:AccountingSupplierParty>
                <cbc:AdditionalAccountID>1</cbc:AdditionalAccountID>
                    <cac:Party>
                        <cac:PartyName>
                            <cbc:Name>GRUPO ERB</cbc:Name>
                        </cac:PartyName>
                        <cac:PhysicalLocation>
                            <cac:Address>
                                <cbc:ID>11001</cbc:ID>
                                <cac:Country>
                                    <cbc:IdentificationCode>CO</cbc:IdentificationCode>
                                </cac:Country>
                            </cac:Address>
                        </cac:PhysicalLocation>
                </cac:Party>
            </cac:AccountingSupplierParty>
        </ext:UBLExtension>
    </ext:UBLExtensions>
</Invoice>
  

пожалуйста, покажите мне, как это сделать, и я сделаю все остальное

Комментарии:

1. то, что вы хотите, можно сделать, но требует много ненужного кодирования. Я думаю, что лучше создать 2 определения схемы xml, одно из которых соответствует исходному выводу sql, а другое — тому, как вы хотели бы, чтобы оно выглядело. Затем используйте такой инструмент, как xsd.exe или xsd2code.exe для создания классов для этих файлов. Создайте вывод sql xml в классе, создайте сопоставление, в котором вы заполняете класс пространствами имен. и когда закончите, сериализуйте его.

2. Согласитесь, взгляните на xsd2code, может дать вам представление о том, как решить эту проблему с разных сторон

3. Спасибо Martijn, но я не понимаю, что вы имеете в виду, говоря о создании двух схем, я новичок в этом, можете ли вы быть немного более откровенным, может быть, вы можете показать мне пример того, как использовать xsd.exe , Я был бы признателен за это….

4. Привет, martijn, я только что использовал xsd.exe и сгенерируйте класс, этот класс очень большой, потому что мне нужно было использовать 7 xsd-файлов. Теперь как сгенерировать XML из этого класса?

Ответ №1:

Это даст вам представление о том, как решить вашу проблему. Я создал небольшой пример. это далеко от совершенства, но в basic показано, какие шаги предпринять.

сначала пространство имен без xsd определяется как:

 <?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:element name="Root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Parent">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="Child1" type="xs:string"/>
                            <xs:element name="Child2" type="xs:string"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>
  

затем из-за разных пространств имен в вашем сообщении я создал одно и то же сообщение с разными пространствами имен. Каждое пространство имен представляет собой отдельный файл.

Root.xsd

 <?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/Root" xmlns:p="http://tempuri.org/Parent" targetNamespace="http://tempuri.org/Root" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:import namespace="http://tempuri.org/Parent" schemaLocation="Parent.xsd"/>
    <xs:element name="Root" type="p:ParentType"/>
</xs:schema>
  

parent.xsd

 <?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/Parent" xmlns:ch="http://tempuri.org/Child" targetNamespace="http://tempuri.org/Parent" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:import namespace="http://tempuri.org/Child" schemaLocation="Child.xsd"/>
    <xs:complexType name="ParentType">
        <xs:sequence>
            <xs:element name="Parent" type="ch:ChildType"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>
  

Дочерний файл.xsd

 <?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns="http://tempuri.org/Child1" targetNamespace="http://tempuri.org/Child">
    <xs:complexType name="ChildType">
        <xs:sequence>
            <xs:element name="Child1" type="xs:string"/>
            <xs:element name="Child2" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>
  

Следующий шаг — создать файлы классов с помощью xsd.exe . Я использую файл bat для выполнения команд te.

 @echo off
set exepad=C:Program Files (x86)Microsoft SDKsWindowsv10.0AbinNETFX 4.6.1 Toolsxsd.exe
set sourcepad=....

set xsdpad=%sourcepad%consolexsd
set Outpad=%sourcepad%consolegenerated

Set NameSpace=Console.generated

"%exepad%" "%xsdpad%NoNSmessage.xsd"  /c  /n:%NameSpace%  /o:%Outpad%

"%exepad%" "%xsdpad%Child.xsd" "%xsdpad%Parent.xsd" "%xsdpad%Root.xsd"  /c  /n:%NameSpace%  /o:%Outpad%

pause
  

Затем импортируйте сгенерированные файлы классов в свой проект, чтобы их можно было использовать.

это пример того, как вы можете сопоставить поля из источника в цель.

 static void Main(string[] args)
        {
            const string msg1 = "<Root><Parent><Child1>First</Child1><Child2>Second</Child2></Parent></Root>";

            //deserialize xml string into class object.
            XmlSerializer deserializer = new XmlSerializer(typeof(Root));
            var reader = new StringReader(msg1);
            var noNamespaceRoot = (Root)deserializer.Deserialize(reader);

            //map the fields from the nonamespace msg to the msg with a namespace
            var namespaceRoot = new ParentType();

            namespaceRoot.Parent = new ChildType();
            namespaceRoot.Parent.Child1 = noNamespaceRoot.Parent.Child1;
            namespaceRoot.Parent.Child2 = noNamespaceRoot.Parent.Child2;

            //serialize the class object to a string.
            var serializer = new XmlSerializer(typeof(ParentType));
            var sww = new StringWriter();
            using (XmlWriter writer = XmlWriter.Create(sww))
            {
                serializer.Serialize(writer, namespaceRoot);
            }
            System.Console.WriteLine(sww.ToString());

        }
  

вывод будет:

 <?xml version="1.0" encoding="utf-16"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/Root">
    <Parent xmlns="http://tempuri.org/Parent">
        <Child1 xmlns="http://tempuri.org/Child">First</Child1>
        <Child2 xmlns="http://tempuri.org/Child">Second</Child2>
    </Parent>
</Root>