Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym przykładzie piszemy zapytanie, które pobiera węzły akapitu z dokumentu WordprocessingML. Identyfikuje również styl każdego akapitu.
To zapytanie opiera się na zapytaniu w poprzednim przykładzie Znajdź domyślny styl akapitu, który pobiera domyślny styl z listy stylów. Te informacje są wymagane, aby zapytanie mogło zidentyfikować styl akapitów, które nie mają jawnie ustawionego stylu. Style akapitu w:pPr
są ustawiane przez element; jeśli akapit nie zawiera tego elementu, jest sformatowany przy użyciu stylu domyślnego.
W tym artykule wyjaśniono znaczenie niektórych fragmentów zapytania, a następnie pokazano zapytanie w ramach kompletnego przykładu roboczego.
Przykład: pobieranie wszystkich akapitów w dokumencie oraz style akapitu
Poniższy kod to zapytanie służące do pobierania wszystkich akapitów w dokumencie i ich stylach:
xDoc.Root.Element(w + "body").Descendants(w + "p")
xDoc.Root.<w:body>...<w:p>
To wyrażenie jest podobne do źródła zapytania w poprzednim przykładzie Znajdź domyślny styl akapitu. Główną różnicą jest użycie Descendants osi zamiast Elements osi. Zapytanie używa Descendants osi, ponieważ w dokumentach, które zawierają sekcje, akapity nie będą bezpośrednimi elementami podrzędnymi elementu treści, a akapity będą dwoma poziomami w hierarchii. Korzystając z Descendants osi, kod będzie działać niezależnie od tego, czy dokument używa sekcji.
Przykład: użyj klauzuli let
, aby określić element zawierający węzeł stylu
Następujące zapytanie używa klauzuli let
, aby określić element zawierający węzeł stylu:
let styleNode = para.Elements(w + "pPr").Elements(w + "pStyle").FirstOrDefault()
Let styleNode As XElement = para.<w:pPr>.<w:pStyle>.FirstOrDefault()
Klauzula let
(Let
w wersji języka Visual Basic) najpierw używa Elements osi do znajdowania wszystkich elementów o nazwie , a następnie używa Elements metody rozszerzenia do znajdowania wszystkich elementów podrzędnych o nazwie pPr
pStyle
, a na koniec używa standardowego FirstOrDefault operatora zapytania, aby przekonwertować kolekcję na pojedynczą. Jeśli kolekcja jest pusta, styleNode
jest ustawiona na null
(Nothing
w wersji Visual Basic). Jest to przydatny idiom do wyszukiwania węzła podrzędnego pStyle
. Należy pamiętać, że jeśli pPr
węzeł podrzędny nie istnieje, kod nie powiedzie się, zgłaszając wyjątek; zamiast tego styleNode
jest ustawiona wartość null
(Nothing
), która jest pożądanym zachowaniem tej let
klauzuli (Let
).
Jeśli nie ma żadnego elementu, styleNode
zostanie ustawiona wartość null
(Nothing
).
Zapytanie projektuje kolekcję typu anonimowego z dwoma elementami członkowskimi StyleName
i ParagraphNode
.
Przykład: pobieranie węzłów akapitu z dokumentu WordprocessingML
Ten przykład przetwarza dokument WordprocessingML, pobierając węzły akapitu. Identyfikuje również styl każdego akapitu. Ten przykład opiera się na poprzednich przykładach w tym samouczku. Nowe zapytanie jest wywoływane w komentarzach w poniższym kodzie.
Instrukcje dotyczące tworzenia dokumentu źródłowego dla tego przykładu znajdują się w artykule Tworzenie źródłowego dokumentu Office Open XML.
W tym przykładzie użyto klas znalezionych w zestawie WindowsBase. Używa typów w System.IO.Packaging przestrzeni nazw.
const string fileName = "SampleDoc.docx";
const string documentRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
const string stylesRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
const string wordmlNamespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XNamespace w = wordmlNamespace;
XDocument xDoc = null;
XDocument styleDoc = null;
using (Package wdPackage = Package.Open(fileName, FileMode.Open, FileAccess.Read))
{
PackageRelationship docPackageRelationship = wdPackage.GetRelationshipsByType(documentRelationshipType).FirstOrDefault();
if (docPackageRelationship != null)
{
Uri documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative), docPackageRelationship.TargetUri);
PackagePart documentPart = wdPackage.GetPart(documentUri);
// Load the document XML in the part into an XDocument instance.
xDoc = XDocument.Load(XmlReader.Create(documentPart.GetStream()));
// Find the styles part. There will only be one.
PackageRelationship styleRelation = documentPart.GetRelationshipsByType(stylesRelationshipType).FirstOrDefault();
if (styleRelation != null)
{
Uri styleUri = PackUriHelper.ResolvePartUri(documentUri, styleRelation.TargetUri);
PackagePart stylePart = wdPackage.GetPart(styleUri);
// Load the style XML in the part into an XDocument instance.
styleDoc = XDocument.Load(XmlReader.Create(stylePart.GetStream()));
}
}
}
string defaultStyle =
(string)(
from style in styleDoc.Root.Elements(w + "style")
where (string)style.Attribute(w + "type") == "paragraph"&&
(string)style.Attribute(w + "default") == "1"
select style
).First().Attribute(w + "styleId");
// Following is the new query that finds all paragraphs in the
// document and their styles.
var paragraphs =
from para in xDoc
.Root
.Element(w + "body")
.Descendants(w + "p")
let styleNode = para
.Elements(w + "pPr")
.Elements(w + "pStyle")
.FirstOrDefault()
select new
{
ParagraphNode = para,
StyleName = styleNode != null ?
(string)styleNode.Attribute(w + "val") :
defaultStyle
};
foreach (var p in paragraphs)
Console.WriteLine("StyleName:{0}", p.StyleName);
Imports <xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
Module Module1
Private Function GetStyleOfParagraph(ByVal styleNode As XElement, ByVal defaultStyle As String) As String
If (styleNode Is Nothing) Then
Return defaultStyle
Else
Return styleNode.@w:val
End If
End Function
Sub Main()
Dim fileName = "SampleDoc.docx"
Dim documentRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
Dim stylesRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"
Dim wordmlNamespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
Dim xDoc As XDocument = Nothing
Dim styleDoc As XDocument = Nothing
Using wdPackage As Package = Package.Open(fileName, FileMode.Open, FileAccess.Read)
Dim docPackageRelationship As PackageRelationship = wdPackage.GetRelationshipsByType(documentRelationshipType).FirstOrDefault()
If (docPackageRelationship IsNot Nothing) Then
Dim documentUri As Uri = PackUriHelper.ResolvePartUri(New Uri("/", UriKind.Relative), docPackageRelationship.TargetUri)
Dim documentPart As PackagePart = wdPackage.GetPart(documentUri)
' Load the document XML in the part into an XDocument instance.
xDoc = XDocument.Load(XmlReader.Create(documentPart.GetStream()))
' Find the styles part. There will only be one.
Dim styleRelation As PackageRelationship = documentPart.GetRelationshipsByType(stylesRelationshipType).FirstOrDefault()
If (styleRelation IsNot Nothing) Then
Dim styleUri As Uri = PackUriHelper.ResolvePartUri(documentUri, styleRelation.TargetUri)
Dim stylePart As PackagePart = wdPackage.GetPart(styleUri)
' Load the style XML in the part into an XDocument instance.
styleDoc = XDocument.Load(XmlReader.Create(stylePart.GetStream()))
End If
End If
End Using
Dim defaultStyle As String = _
( _
From style In styleDoc.Root.<w:style> _
Where style.@w:type = "paragraph" And _
style.@w:default = "1" _
Select style _
).First().@w:styleId
' Following is the new query that finds all paragraphs in the
' document and their styles.
Dim paragraphs = _
From para In xDoc.Root.<w:body>...<w:p> _
Let styleNode As XElement = para.<w:pPr>.<w:pStyle>.FirstOrDefault() _
Select New With { _
.ParagraphNode = para, _
.StyleName = GetStyleOfParagraph(styleNode, defaultStyle) _
}
For Each p In paragraphs
Console.WriteLine("StyleName:{0}", p.StyleName)
Next
End Sub
End Module
Ten przykład generuje następujące wyniki:
StyleName:Heading1
StyleName:Normal
StyleName:Normal
StyleName:Normal
StyleName:Code
StyleName:Code
StyleName:Code
StyleName:Code
StyleName:Code
StyleName:Code
StyleName:Code
StyleName:Normal
StyleName:Normal
StyleName:Normal
StyleName:Code
W następnym artykule w tym samouczku pokazano, jak utworzyć zapytanie w celu pobrania tekstu akapitów: