/// <summary> /// Gets current Property/ScoredProperty's QName LocalName value from its "Value" child-element. /// The returned property QName value is guaranteed to be in the standard keyword set namespace. /// </summary> /// <exception cref="FormatException">either can't find the value or value is private</exception> /// <exception cref="XmlException">XML is not well-formed.</exception> public string GetCurrentPropertyQNameValueWithException() { string QName = GetCurrentPropertyFullValueWithException(); if (XmlReaderQName.GetURI(_xmlReader, QName) == PrintSchemaNamespaces.StandardKeywordSet) { return(XmlReaderQName.GetLocalName(QName)); } else { // Needs to handle private XML text value throw NewPrintCapFormatException(String.Format(CultureInfo.CurrentCulture, PTUtility.GetTextFromResource("FormatException.PrivateXMLTextValue"), QName, _xmlReader.LineNumber, _xmlReader.LinePosition)); } }
/// <summary> /// Moves the reader cursor to the next Print Schema Framework element at the given depth. /// (The element could be Feature, ParameterDefinition, Option, ScoredProperty or Property) /// </summary> /// <param name="depth">client-requested traversing depth</param> /// <param name="typeFilterFlags">flags to indicate client interested node types</param> /// <returns>True if next Framework element is ready to read. /// False if no more Framework element at the given depth.</returns> /// <exception cref="XmlException">XML is not well-formed.</exception> public bool MoveToNextSchemaElement(int depth, PrintSchemaNodeTypes typeFilterFlags) { bool foundElement = false; while (!foundElement && _xmlReader.Read()) { // Read() throws XmlException if error occurred while parsing the XML. // If we hit an end-element tag at higher depth, we know there are no more // Framework elements at the client-requested depth. if ((_xmlReader.NodeType == XmlNodeType.EndElement) && (_xmlReader.Depth < depth)) { break; } // Stop at the next XML start element at the client-requested depth // and in the standard Framework element namespace. if ((_xmlReader.NodeType != XmlNodeType.Element) || (_xmlReader.Depth != depth) || (_xmlReader.NamespaceURI != PrintSchemaNamespaces.Framework)) { continue; } // Find a candidate, so reset internal states to be ready for its parsing. ResetCurrentElementState(); foundElement = true; _currentElementDepth = depth; _currentElementIsEmpty = _xmlReader.IsEmptyElement; // Map element name to Schema node type int enumValue = PrintSchemaMapper.SchemaNameToEnumValueWithMap( PrintSchemaTags.Framework.NodeTypeMapTable, _xmlReader.LocalName); if (enumValue > 0) { _currentElementNodeType = (PrintSchemaNodeTypes)enumValue; } else { #if _DEBUG Trace.WriteLine("-Warning- skip unknown element '" + _xmlReader.LocalName + "' at line " + _xmlReader.LineNumber + ", position " + _xmlReader.LinePosition); #endif foundElement = false; } if (foundElement) { // Check whether or not the found element type is what client is interested in. // If not, we will skip this element. if ((CurrentElementNodeType & typeFilterFlags) == 0) { #if _DEBUG Trace.WriteLine("-Warning- skip not-wanted element '" + _xmlReader.LocalName + "' at line " + _xmlReader.LineNumber + ", position " + _xmlReader.LinePosition); #endif foundElement = false; } } if (foundElement) { // The element is what the client wants. if (CurrentElementNodeType != PrintSchemaNodeTypes.Value) { // Element other than <Value> should have the "name" XML attribute. // Reader will verify the "name" XML attribute has a QName value that // is in our standard Keyword namespace. string QName = _xmlReader.GetAttribute(PrintSchemaTags.Framework.NameAttr, PrintSchemaNamespaces.FrameworkAttrForXmlReader); // Only <Option> element is allowed not to have the "name" XML attribute if (QName == null) { if (CurrentElementNodeType != PrintSchemaNodeTypes.Option) { #if _DEBUG Trace.WriteLine("-Warning- skip element " + CurrentElementNodeType + " at line " + _xmlReader.LineNumber + ", position " + _xmlReader.LinePosition + " due to missing 'name' XML attribute"); #endif foundElement = false; } } else { string URI = XmlReaderQName.GetURI(_xmlReader, QName); string localName = XmlReaderQName.GetLocalName(QName); if (URI == PrintSchemaNamespaces.Framework) { _currentElementPSFNameAttrValue = localName; } else if (URI == PrintSchemaNamespaces.StandardKeywordSet) { _currentElementNameAttrValue = localName; } else { // If QName value is not in standard PSF or PSK namespace, // then skip this Schema element. #if _DEBUG Trace.WriteLine("-Warning- skip element " + CurrentElementNodeType + " at line " + _xmlReader.LineNumber + ", position " + _xmlReader.LinePosition + " due to non-PSF/PSK 'name' XML attribute value: " + QName); #endif foundElement = false; } } } else { // For <Value> element, we need to get its element text value. // If this function tells client the <Value> element is found, it guarantees // that the <Value> element text value is non-empty. // Needs to handle xsi:type verification // ReadElementString() returns empty string if the element is empty // (<item></item> or <item/>), and it could throws XmlException. _currentElementTextValue = _xmlReader.ReadElementString(); // Our schema requires that <Value> element should always have non-empty value. if ((_currentElementTextValue == null) || (_currentElementTextValue.Length == 0)) { #if _DEBUG Trace.WriteLine("-Warning- skip element " + CurrentElementNodeType + " at line " + _xmlReader.LineNumber + ", position " + _xmlReader.LinePosition + " since it has empty element text"); #endif _currentElementTextValue = null; foundElement = false; } } } } return(foundElement); }