문제

XML 아래로 요소를 형성하는 XML '스 니펫'으로 작업하고 있습니다. 스키마가 있지만이 파일은 완전한 XML 문서가 아니기 때문에이 파일을 검증 할 수 없습니다. 이 스 니펫은 다른 도구에 사용될 때 유효한 XML을 형성하기 위해 필요한 상위 요소로 싸여 있으므로 유효한 XML로 만들거나 스키마를 변경하는 데 많은 옵션이 없습니다.

전체 문서보다는 요소를 검증 할 수 있습니까? 그렇지 않다면 어떤 해결 방법을 제안 할 수 있습니까?

.NET 2.0 프레임 워크와 함께 C#에서 작업하고 있습니다.

도움이 되었습니까?

해결책

XML 문서의 일부만 검증 할 수있는 비슷한 문제가있었습니다. 이 방법을 여기에서 생각해 냈습니다.

private void ValidateSubnode(XmlNode node, XmlSchema schema)
{
    XmlTextReader reader = new XmlTextReader(node.OuterXml, XmlNodeType.Element, null);

    XmlReaderSettings settings = new XmlReaderSettings();
    settings.ConformanceLevel = ConformanceLevel.Fragment;
    settings.Schemas.Add(schema);
    settings.ValidationType = ValidationType.Schema;
    settings.ValidationEventHandler += new ValidationEventHandler(XSDValidationEventHandler);

    using (XmlReader validationReader = XmlReader.Create(reader, settings))
    {     
        while (validationReader.Read())
        {
        }
    }
}

private void XSDValidationEventHandler(object sender, ValidationEventArgs args)
{
    errors.AppendFormat("XSD - Severity {0} - {1}", 
                        args.Severity.ToString(), args.Message);
}

기본적으로 XMLNode (.SelectSingLenode를 통해 전체 XMLDocument에서 선택한 XMLDocument에서 선택) 및 앱 내부 리소스 XSD에서로드하는 XML 스키마를 전달합니다. 발생할 수있는 유효성 검사 오류는 "오류"문자열 빌더로 채워져서 끝에 읽은 다음 오류가 기록되어 있는지 여부를 확인합니다.

나를 위해 일합니다 - 당신의 마일리지는 다를 수 있습니다 :-)

다른 팁

이있다 XmlDocument.Validate 방법을 취하는 방법 XmlNode 인수 로서이 노드 만 검증합니다. 그게 당신이 찾고있는 것일 수 있습니다 ...

좋아, 여기 또 다른 접근법이있다 :

XSLT 변환을 사용하여 스키마 파일을 스 니펫 요소를 루트로 갖는 새 스키마로 변환 할 수 있습니다. 원래 스키마가 될 것이라고 말하십시오

<xs:schema id="MySchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="RootElement">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="NestedElement">
          <xs:complexType>
            <xs:attribute name="Name" type="xs:string" use="required"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

당신은 유형의 스 니펫이 있습니다 NestedElement 검증을 원한다는 것 :

<NestedElement Name1="Name1" />

그런 다음 XSLT 템플릿과 같은 템플릿을 사용할 수 있습니다

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="xs:element[@name='NestedElement']"
                xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:schema id="MySchema">
      <xsl:copy-of select="."/>
    </xs:schema>
  </xsl:template>
</xsl:stylesheet>

새로운 스키마를 만들려면 NestedElement 루트로. 결과 스키마는 모양이 될 것입니다

<xs:schema id="MySchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="NestedElement">
    <xs:complexType>
      <xs:attribute name="Name" type="xs:string" use="required" />
    </xs:complexType>
  </xs:element>
</xs:schema>

그런 다음 코드와 같은 코드를 사용 하여이 새 스키마에 대해 스 니펫 문서를 검증 할 수 있습니다.

XmlSchema schema;
using (MemoryStream stream =    new MemoryStream())
using (FileStream fs = new FileStream("MySchema.xsd", FileMode.Open))
using(XmlReader reader = XmlReader.Create(fs)) {
  XslCompiledTransform transform = new XslCompiledTransform();
  transform.Load("SchemaTransform.xslt");
  transform.Transform(reader, null, stream);
  stream.Seek(0, SeekOrigin.Begin);
  schema = XmlSchema.Read(stream, null);
}
XmlDocument doc = new XmlDocument();
doc.Schemas.Add(schema);
doc.Load("rootelement.xml");
doc.Validate(ValidationHandler);

MySchema.xsd 원래 스키마, SchemaTransform.xslt 변환 (위와 같이), rootelement.xml 단일 스 니펫 노드를 포함하는 XML 문서입니다.

특수 네임 스페이스 별명을 사용하여 검증하려는 요소를 배정 한 다음 해당 네임 스페이스 별칭에 대한 스키마를 추가 할 수 있지만 다른 사람은 그렇지 않습니다. 이 방법으로 특수 네임 스페이스 접두사가있는 요소 만 검증됩니다.

내가 열망하는 일을하는 것은 불가능한 것 같지 않습니다. 현재의 작업은 빈 템플릿 XML 문서를 만드는 것입니다. 그런 다음 원하는 요소를 내 스 니펫으로 교체하십시오. 거기에서 나는 검증 방법이 실행 가능하다고 생각합니다. 그러나이 템플릿을 동적으로 만드는 것은 그 자체로 또 다른 어려운 작업 인 것 같습니다. '골격'문서를 만드는 쉬운 방법은없는 것 같습니다.

나는 같은 문제가 있었다. 여기서 해결책을 요청했습니다. 해결 방법을 찾았습니다.

문제는 루트 요소 만 검증 될 수 있다는 것입니다. 그래서 ... 메모리에서 체계를 편집하고 루트에 검증하기 위해 요소/유형을 추가합니다.

public static void AddElementToSchema(XmlSchema xmlSchema, string elementName, string elementType, string xmlNamespace)
{
    XmlSchemaElement testNode = new XmlSchemaElement();
    testNode.Name = elementName;
    testNode.Namespaces.Add("", xmlNamespace);
    testNode.SchemaTypeName = new XmlQualifiedName(elementType, xmlNamespace);
    xmlSchema.Items.Add(testNode);
    xmlSchema.Compile(XMLValidationEventHandler);
}

몇 줄 만 있으면 XSD 파일을 수정하거나 추가해서는 안됩니다. :) Memory Inmory 스키마를 간단하게 변경하면 전체 문서를 검증하는 데 사용하는 것과 동일한 코드로 조각을 검증 할 수 있습니다. 검증 할 조각의 루트 요소에 네임 스페이스가 포함되어 있는지 확인하십시오. :)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top